14.1.1-18 baseline

Former-commit-id: 1f27652aa3 [formerly f05a2220cd] [formerly 575e328123] [formerly 1f27652aa3 [formerly f05a2220cd] [formerly 575e328123] [formerly 1d6a9456b7 [formerly 575e328123 [formerly a8009c4ee3effc8586b830244db8db716ec0f37c]]]]
Former-commit-id: 1d6a9456b7
Former-commit-id: 1c7bf39f73 [formerly d61ae6c5f4] [formerly 57fbd21c8831f46d66fe301b77916657b0ab9f05 [formerly c5857c30f2]]
Former-commit-id: 48b7eeaa6cb834b10db17643ac629aaa112f6878 [formerly d1db845406]
Former-commit-id: f47dd3ef59
This commit is contained in:
Brian.Dyke 2014-02-11 15:52:50 -05:00
parent e0236cc20a
commit fc21d2dee4
19 changed files with 546 additions and 145 deletions

View file

@ -107,6 +107,40 @@
</max-perm>
</ini-substitutions>
</memory-setting>
<memory-setting>
<command-line-args>
<first-arg>-component</first-arg>
<second-arg>servicebackup</second-arg>
</command-line-args>
<ini-substitutions>
<max-memory>
<value>256M</value>
</max-memory>
<max-perm>
<value>128m</value>
</max-perm>
</ini-substitutions>
</memory-setting>
<memory-setting>
<command-line-args>
<first-arg>-perspective</first-arg>
<second-arg>National Centers</second-arg>
</command-line-args>
<ini-substitutions>
<max-memory>
<value>1536M</value>
</max-memory>
<max-perm>
<value>DEFAULT</value>
</max-perm>
</ini-substitutions>
</memory-setting>
</arch.x86>
<arch.x86_64>
@ -182,6 +216,40 @@
</max-perm>
</ini-substitutions>
</memory-setting>
<memory-setting>
<command-line-args>
<first-arg>-component</first-arg>
<second-arg>servicebackup</second-arg>
</command-line-args>
<ini-substitutions>
<max-memory>
<value>256M</value>
</max-memory>
<max-perm>
<value>128m</value>
</max-perm>
</ini-substitutions>
</memory-setting>
<memory-setting>
<command-line-args>
<first-arg>-perspective</first-arg>
<second-arg>National Centers</second-arg>
</command-line-args>
<ini-substitutions>
<max-memory>
<value>2048M</value>
</max-memory>
<max-perm>
<value>DEFAULT</value>
</max-perm>
</ini-substitutions>
</memory-setting>
</arch.x86_64>
</cave-memory-settings>

View file

@ -29,11 +29,15 @@
# ??/??/?? ???????? Initial Creation.
# 05/14/13 1842 dgilling Use GFEVtecUtil to handle NEW
# ETN assignment.
# 02/05/14 2774 dgilling Fix error logging statements in
# __warnETNduplication() and
# __highestETNActiveTable.
#
#
import time, getopt, sys, copy, string, logging
import os
import VTECTableUtil, VTECTable
import TimeRange, AbsTime, ActiveTableVtec
import JUtil
@ -722,7 +726,7 @@ class HazardsTable(VTECTableUtil.VTECTableUtil):
if phensig == activephensig and presentyear == activeyear:
# causes failure if tropical hazards are less than 1001
if active['etn'] < int(self.__tpcBaseETN):
LogStream.logProblem("Incorrect ETN for tropical hazard.")
self.log.error("Incorrect ETN for tropical hazard.")
return etn_base
#determine the new etn to use, using the etn cache
@ -2234,8 +2238,8 @@ class HazardsTable(VTECTableUtil.VTECTableUtil):
if len(dups) > 0:
errorLine = '\n******************************************************\n'
LogStream.logProblem("Illegal ETN duplication is found for:\n", \
dups, errorLine)
self.log.error("Illegal ETN duplication is found for:\n" + \
str(dups) + errorLine)
# send message to GFE
msg = "The formatted %s product contains a duplicate ETN.\n"\

View file

@ -29,7 +29,7 @@
# ------------ ---------- ----------- --------------------------
# 07/25/08 njensen Initial Creation.
# 09/05/13 #2329 randerso Added error handling
#
# 02/06/2014 #2591 randerso Changed log level to debug
#
import sys, traceback, os, time, LogStream
@ -55,7 +55,7 @@ def getCombinations(comboName):
with open(filename,'r') as fd:
filecontents = fd.read()
LogStream.logProblem("\nERROR loading combinations file: "+ comboName +
LogStream.logDebug("ERROR loading combinations file: "+ comboName +
"\nmd.__file__: " + md.__file__ +
"\ndir(md): " + str(dir(md)) +
"\n" + md.__file__ + " last modified: " + time.strftime("%Y-%m-%d %H:%M:%S",time.gmtime(os.path.getmtime(md.__file__))) +

View file

@ -29,6 +29,7 @@
# Dec 05, 2013 #2590 dgilling Modified so gfeclient.sh can be wrapped
# around this script.
# Jan 24, 2014 #2739 bsteffen Log exit status
# Jan 30, 2014 #2593 bclement warns based on memory usage, fixed for INI files with spaces
#
#
@ -46,6 +47,8 @@ JAVA_INSTALL="/awips2/java"
PYTHON_INSTALL="/awips2/python"
export AWIPS_INSTALL_DIR="${CAVE_INSTALL}"
MAX_MEM_PROPORTION="0.9"
source ${CAVE_INSTALL}/caveUtil.sh
RC=$?
if [ ${RC} -ne 0 ]; then
@ -113,20 +116,39 @@ export TEXTWS=`hostname | sed -e 's/lx/xt/g'`
hostName=`hostname -s`
if [[ $hostName =~ xt.* ]]; then
export IGNORE_NUM_CAVES=1
fi
# check number of running caves
if [[ -z $IGNORE_NUM_CAVES ]]; then
# free usually reports below on G threshold (11 instead of 12G), giving the 3 cave recommended in field
mem=( `free -g | grep "Mem:"` )
# get total memory on system in bytes
mem=( `free -b | grep "Mem:"` )
mem=${mem[1]}
let _maxCaves=mem/3
getPidsOfMyRunningCaves
if [[ "$_numPids" -ge "$_maxCaves" ]]; then
zenity --question --title "Max CAVE sessions already running" --text "$_numPids CAVE sessions already running. Starting more may impact system performance and stability.\n\nProceed?"
# get max amount of system memory used before we warn
memThreshold=$(echo "$mem * $MAX_MEM_PROPORTION" | bc)
# remove decimal
printf -v memThreshold "%.0f" "$memThreshold"
# get launcher.ini argument determined by user arguments
lookupINI "$@"
launcherRegex='--launcher.ini\s(.+\.ini)'
# default to cave.ini
targetIni="/awips2/cave/cave.ini"
if [[ $CAVE_INI_ARG =~ $launcherRegex ]]
then
targetIni="${BASH_REMATCH[1]}"
fi
# read max memory that could be used by this instance
memOfLaunchingCave=$(readMemFromIni "$targetIni")
# read total max memory of caves already running
getTotalMemOfRunningCaves
# add them together
_totalAfterStart=$(($memOfLaunchingCave + $_totalRunningMem))
if [[ "$_totalAfterStart" -ge "$memThreshold" ]]; then
# convert to megs for display
memOfLaunchingCave=$(($memOfLaunchingCave / $BYTES_IN_MB))
_totalRunningMem=$(($_totalRunningMem / $BYTES_IN_MB))
getPidsOfMyRunningCaves
memMsg="$_numPids CAVE applications already running with a combined max memory of ${_totalRunningMem}MB. "
memMsg+="The requested application has a max memory requirement of ${memOfLaunchingCave}MB. "
memMsg+="Starting may impact system performance and stability.\n\nProceed?"
zenity --question --title "Low Available Memory for Application" --text "$memMsg"
cancel="$?"
if [[ "$cancel" == "1" ]]; then
@ -181,7 +203,7 @@ curTime=`date +%Y%m%d_%H%M%S`
# At this point fork so that log files can be set up with the process pid and
# this process can log the exit status of cave.
(
export pid=`$SHELL -c 'echo $PPID'`
export pid=`/bin/bash -c 'echo $PPID'`
LOGFILE="${LOGDIR}/${PROGRAM_NAME}_${curTime}_pid_${pid}_console.log"
export LOGFILE_CAVE="${LOGDIR}/${PROGRAM_NAME}_${curTime}_pid_${pid}_alertviz.log"
@ -221,9 +243,9 @@ curTime=`date +%Y%m%d_%H%M%S`
fi
if [[ "${redirect}" == "true" ]] ; then
exec ${CAVE_INSTALL}/cave ${ARCH_ARGS} ${SWITCHES} ${CAVE_INI_ARG} "${USER_ARGS[@]}" > ${LOGFILE} 2>&1
exec ${CAVE_INSTALL}/cave ${ARCH_ARGS} ${SWITCHES} "${CAVE_INI_ARG}" "${USER_ARGS[@]}" > ${LOGFILE} 2>&1
else
exec ${CAVE_INSTALL}/cave ${ARCH_ARGS} ${SWITCHES} ${CAVE_INI_ARG} "${USER_ARGS[@]}" 2>&1 | tee ${LOGFILE}
exec ${CAVE_INSTALL}/cave ${ARCH_ARGS} ${SWITCHES} "${CAVE_INI_ARG}" "${USER_ARGS[@]}" 2>&1 | tee ${LOGFILE}
fi
) &

View file

@ -26,6 +26,9 @@
# Dec 05, 2013 #2590 dgilling Modified extendLibraryPath() to export a
# var if it's already been run.
# Jan 24, 2014 #2739 bsteffen Add method to log exit status of process.
# 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
#
#
@ -40,6 +43,10 @@ fi
# This script will be sourced by cave.sh.
export CAVE_INI_ARG=
BYTES_IN_KB=1024
BYTES_IN_MB=1048576
BYTES_IN_GB=1073741824
function lookupINI()
{
# Arguments:
@ -56,7 +63,7 @@ function lookupINI()
position=$(( $position + 1 ))
nextArg=${!position}
retrieveAssociatedINI ${arg} ${nextArg}
retrieveAssociatedINI ${arg} "${nextArg}"
RC=$?
if [ ${RC} -eq 0 ]; then
export CAVE_INI_ARG="--launcher.ini /awips2/cave/${ASSOCIATED_INI}"
@ -117,8 +124,8 @@ function copyVizShutdownUtilIfNecessary()
chmod a+x ${HOME}/.kde/shutdown/${VIZ_UTILITY_SCRIPT}
}
# returns _numPids and array _pids containing the pids of the currently running cave sessions.
function getPidsOfMyRunningCaves()
# takes a function as an argument and calls the function passing in the ps string of the process
function forEachRunningCave()
{
local user=`whoami`
local caveProcs=`ps -ef | grep -E "(/awips2/cave|/usr/local/viz)/cave " | grep -v "grep" | grep $user`
@ -126,17 +133,89 @@ function getPidsOfMyRunningCaves()
# preserve IFS and set it to line feed only
local PREV_IFS=$IFS
IFS=$'\n'
_numPids=0
# grab the pids for future use
for caveProc in $caveProcs
do
_pids[$_numPids]=`echo $caveProc | awk '{print $2}'`
let "_numPids+=1"
"$@" $caveProc
done
IFS=$PREV_IFS
}
# takes in ps string of cave process, stores pid in _pids and increments _numPids
function processPidOfCave()
{
_pids[$_numPids]=`echo $1 | awk '{print $2}'`
let "_numPids+=1"
}
# returns _numPids and array _pids containing the pids of the currently running cave sessions.
function getPidsOfMyRunningCaves()
{
_numPids=0
forEachRunningCave processPidOfCave
}
# takes a name of an ini file as an argument, echos the memory (in bytes) from file (or default)
function readMemFromIni()
{
local inifile="$1"
local mem
local unit
local regex='^[^#]*-Xmx([0-9]+)([bBkKmMgG])?'
# read ini file line by line looking for Xmx arg
while read -r line
do
if [[ $line =~ $regex ]]
then
mem=${BASH_REMATCH[1]}
unit=${BASH_REMATCH[2]}
break
fi
done < "$inifile"
# convert to bytes
case "$unit" in
[kK])
mem=$(($mem * $BYTES_IN_KB))
;;
[mM])
mem=$(($mem * $BYTES_IN_MB))
;;
[gG])
mem=$(($mem * $BYTES_IN_GB))
;;
esac
regex='^[0-9]+$'
if [[ ! $mem =~ $regex ]]
then
# we couldn't find a valid Xmx value
# java default is usually 1G
mem=1073741824
fi
echo $mem
}
# takes in ps string of cave process, reads Xmx from ini and adds bytes to _totalRunninMem
function addMemOfCave()
{
local inifile
# get ini file from process string
local regex='--launcher.ini\s(.+\.ini)'
if [[ $1 =~ $regex ]]
then
inifile="${BASH_REMATCH[1]}"
else
inifile="/awips2/cave/cave.ini"
fi
let "_totalRunningMem+=$(readMemFromIni "$inifile")"
}
# finds total max memory of running caves in bytes and places it in _totalRunningMem
function getTotalMemOfRunningCaves()
{
_totalRunningMem=0
forEachRunningCave addMemOfCave
}
function deleteOldCaveDiskCaches()
{
local curDir=`pwd`
@ -201,6 +280,7 @@ function logExitStatus()
pid=$1
logFile=$2
trap 'kill $pid' SIGHUP SIGINT SIGQUIT SIGTERM
wait $pid
exitCode=$?
curTime=`date --rfc-3339=seconds`

View file

@ -81,6 +81,7 @@ import com.raytheon.viz.ui.dialogs.CaveSWTDialog;
* archive and category directory and
* implementation of compression.
* Oct 08, 2013 2442 rferrel Remove category directory.
* Feb 04, 2013 2270 rferrel Move HDF files to parent's directory.
*
* </pre>
*
@ -89,6 +90,10 @@ import com.raytheon.viz.ui.dialogs.CaveSWTDialog;
*/
public class GenerateCaseDlg extends CaveSWTDialog {
/** Extension for HDF files. */
private static final String hdfExt = ".h5";
private final IUFStatusHandler statusHandler = UFStatus
.getHandler(GenerateCaseDlg.class);
@ -539,6 +544,11 @@ public class GenerateCaseDlg extends CaveSWTDialog {
new File(destination, file));
}
} else {
// DR 2270 bump HDF files up a directory.
if (destination.getName().endsWith(hdfExt)) {
destination = new File(destination.getParentFile()
.getParentFile(), destination.getName());
}
FileUtil.copyFile(source, destination);
destination.setLastModified(source.lastModified());
}
@ -652,6 +662,13 @@ public class GenerateCaseDlg extends CaveSWTDialog {
addTarFiles(file.listFiles());
}
} else {
// DR 2270 bump HDF files up a directory.
if (name.endsWith(hdfExt)) {
File destination = new File(file.getParentFile()
.getParentFile(), file.getName());
name = destination.getAbsolutePath().substring(
startRelativePath);
}
TarArchiveEntry entry = new TarArchiveEntry(file, name);
entry.setSize(file.length());
FileInputStream fileStream = null;

View file

@ -63,6 +63,7 @@ import com.raytheon.viz.gfe.textformatter.TextProductManager;
* DataManager instance.
* 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
*
* </pre>
*
@ -592,7 +593,7 @@ public class ProductAreaComp extends Composite implements
*/
private void createZoneCombinerComp() {
zoneCombiner = new ZoneCombinerComp(stackGridComp, productTabCB,
productName, getTextProductManager());
productName, getTextProductManager(), this.dataMgr);
}
/**

View file

@ -155,6 +155,7 @@ import com.raytheon.viz.ui.dialogs.ICloseCallback;
* 01/06/2014 2649 dgilling Pass flag to StoreTransmitDlg to only
* update VTEC lines on products that
* aren't being corrected.
* 02/05/2014 17022 ryu Modified loadDraft() to fix merging of WMO heading and AWIPS ID.
*
* </pre>
*
@ -2389,10 +2390,13 @@ public class ProductEditorComp extends Composite implements
}
DraftProduct draft = DraftProduct.load(lf);
setTabColorFunc(productStateEnum.Finished);
productDefinition = draft.getProductDefinition();
clearProductText();
setProductText(draft.getProductText());
setTabColorFunc(productStateEnum.Finished);
setStatusText('R', productId + " draft loaded.");
if (productDefinition.get("brain") != null) {
brain();
String msg = "Your saved draft was loaded, but the draft is invalid "

View file

@ -58,8 +58,7 @@ import org.opengis.referencing.operation.TransformException;
import com.raytheon.uf.common.dataplugin.gfe.db.objects.GridLocation;
import com.raytheon.uf.common.dataplugin.gfe.exception.GfeException;
import com.raytheon.uf.common.localization.FileUpdatedMessage;
import com.raytheon.uf.common.localization.ILocalizationFileObserver;
import com.raytheon.uf.common.dataplugin.gfe.server.notify.CombinationsFileChangedNotification;
import com.raytheon.uf.common.localization.IPathManager;
import com.raytheon.uf.common.localization.LocalizationContext;
import com.raytheon.uf.common.localization.LocalizationContext.LocalizationLevel;
@ -74,7 +73,9 @@ import com.raytheon.uf.viz.core.RGBColors;
import com.raytheon.uf.viz.core.VizApp;
import com.raytheon.uf.viz.core.exception.VizException;
import com.raytheon.viz.gfe.Activator;
import com.raytheon.viz.gfe.core.DataManager;
import com.raytheon.viz.gfe.core.DataManagerUIFactory;
import com.raytheon.viz.gfe.core.internal.NotificationRouter.AbstractGFENotificationObserver;
import com.raytheon.viz.gfe.textformatter.CombinationsFileUtil;
import com.raytheon.viz.gfe.textformatter.TextProductManager;
import com.raytheon.viz.gfe.ui.zoneselector.ZoneSelector;
@ -100,6 +101,11 @@ import com.raytheon.viz.gfe.ui.zoneselector.ZoneSelector;
* Dec 03, 2013 #2591 dgilling Ensure all change states to the combo
* file are handled.
* Jan 07, 2014 #2662 randerso Disabled zone combiner if no maps are selected
* Feb 04, 2014 #2591 randerso Forced reload of combinations file after save to ensure
* file is updated prior to running formatter
* Changed to use CombinationsFileChangedNotification instead of
* FileUpdatedMessage so we can ignore our own changes
* Moved retrieval of combinations file to CombinationsFileUtil.init
*
* </pre>
*
@ -107,8 +113,7 @@ import com.raytheon.viz.gfe.ui.zoneselector.ZoneSelector;
* @version 1.0
*
*/
public class ZoneCombinerComp extends Composite implements
ILocalizationFileObserver, IZoneCombiner {
public class ZoneCombinerComp extends Composite implements IZoneCombiner {
private final transient IUFStatusHandler statusHandler = UFStatus
.getHandler(ZoneCombinerComp.class);
@ -191,6 +196,8 @@ public class ZoneCombinerComp extends Composite implements
protected TextProductManager textProductMgr;
protected DataManager dataManager;
protected String product;
protected boolean mapRequired;
@ -224,6 +231,8 @@ public class ZoneCombinerComp extends Composite implements
private List<String> mapNames;
private AbstractGFENotificationObserver<CombinationsFileChangedNotification> comboChangeListener;
private void initPreferences() {
IPreferenceStore prefs = Activator.getDefault().getPreferenceStore();
@ -247,7 +256,8 @@ public class ZoneCombinerComp extends Composite implements
* Product name.
*/
public ZoneCombinerComp(Composite parent, IProductTab callBack,
String productName, TextProductManager textProductMgr) {
String productName, TextProductManager textProductMgr,
DataManager dataManager) {
super(parent, SWT.NONE);
this.parent = parent;
@ -258,6 +268,8 @@ public class ZoneCombinerComp extends Composite implements
this.textProductMgr = textProductMgr;
this.dataManager = dataManager;
mapRequired = this.textProductMgr.mapRequired(productName);
this.mapNames = getMapNames(productName);
if (mapNames.isEmpty()) {
@ -272,15 +284,30 @@ public class ZoneCombinerComp extends Composite implements
LocalizationType.CAVE_STATIC, LocalizationLevel.BASE);
comboDir = pathMgr.getLocalizationFile(baseCtx,
CombinationsFileUtil.COMBO_DIR_PATH);
comboDir.addFileUpdatedObserver(this);
this.comboChangeListener = new AbstractGFENotificationObserver<CombinationsFileChangedNotification>(
CombinationsFileChangedNotification.class) {
@Override
public void notify(
CombinationsFileChangedNotification notificationMessage) {
comboFileChanged(notificationMessage);
}
};
this.addDisposeListener(new DisposeListener() {
@Override
public void widgetDisposed(DisposeEvent e) {
comboDir.removeFileUpdatedObserver(ZoneCombinerComp.this);
ZoneCombinerComp.this.dataManager.getNotificationRouter()
.removeObserver(
ZoneCombinerComp.this.comboChangeListener);
}
});
dataManager.getNotificationRouter().addObserver(
this.comboChangeListener);
}
private List<String> getMapNames(String productName) {
@ -779,9 +806,14 @@ public class ZoneCombinerComp extends Composite implements
}
try {
String comboName = getCombinationsFileName();
CombinationsFileUtil.generateAutoCombinationsFile(
zoneSelector.getZoneGroupings(), getCombinationsFileName()
+ ".py");
zoneSelector.getZoneGroupings(), comboName);
// reload here forces file to be retrieved from server before
// allowing formatter to run
loadCombinationsFile(comboName);
applyButtonState(false);
} catch (Exception e) {
statusHandler.handle(Priority.PROBLEM, "Unable to save "
@ -925,17 +957,7 @@ public class ZoneCombinerComp extends Composite implements
public Map<String, Integer> loadCombinationsFile(String comboName) {
Map<String, Integer> dict = new HashMap<String, Integer>();
try {
File localFile = PathManagerFactory.getPathManager().getStaticFile(
FileUtil.join(CombinationsFileUtil.COMBO_DIR_PATH,
comboName + ".py"));
List<List<String>> combolist = new ArrayList<List<String>>();
if ((localFile != null) && localFile.exists()) {
combolist = CombinationsFileUtil.init(comboName);
} else {
// statusHandler
// .error("Combinations file not found: " + comboName);
}
List<List<String>> combolist = CombinationsFileUtil.init(comboName);
// reformat combinations into combo dictionary
int group = 1;
@ -951,8 +973,7 @@ public class ZoneCombinerComp extends Composite implements
return new HashMap<String, Integer>();
}
currentComboFile = FileUtil.join(CombinationsFileUtil.COMBO_DIR_PATH,
comboName + ".py");
currentComboFile = comboName;
return dict;
}
@ -987,20 +1008,14 @@ public class ZoneCombinerComp extends Composite implements
return colors;
}
/*
* (non-Javadoc)
*
* @see
* com.raytheon.uf.common.localization.ILocalizationFileObserver#fileUpdated
* (com.raytheon.uf.common.localization.FileUpdatedMessage)
*/
@Override
public void fileUpdated(FileUpdatedMessage message) {
if (message.getFileName().equalsIgnoreCase(currentComboFile)) {
File file = new File(message.getFileName());
String comboName = file.getName().replace(".py", "");
private void comboFileChanged(CombinationsFileChangedNotification notif) {
String comboName = notif.getCombinationsFileName();
// if it's the same file and not changed by me update the combos
if (comboName.equalsIgnoreCase(currentComboFile)
&& !VizApp.getWsId().equals(notif.getWhoChanged())) {
statusHandler
.info("Received FileUpdatedMessage for combinations file: "
.info("Received CombinationsFileChangedNotification for combinations file: "
+ comboName);
Map<String, Integer> comboDict = loadCombinationsFile(comboName);
this.zoneSelector.updateCombos(comboDict);

View file

@ -52,6 +52,7 @@ import com.raytheon.uf.common.serialization.SerializationException;
import com.raytheon.uf.common.serialization.SerializationUtil;
import com.raytheon.uf.common.status.IUFStatusHandler;
import com.raytheon.uf.common.status.UFStatus;
import com.raytheon.uf.common.status.UFStatus.Priority;
import com.raytheon.uf.common.util.FileUtil;
import com.raytheon.viz.gfe.core.DataManagerUIFactory;
import com.raytheon.viz.gfe.core.internal.IFPClient;
@ -67,6 +68,8 @@ import com.raytheon.viz.gfe.textformatter.CombinationsFileUtil.ComboData.Entry;
* Jul 25, 2008 mnash Initial creation
* Sep 05, 2013 #2329 randerso Moved genereateAutoCombinationsFile here
* Cleaned up error handling
* Feb 05, 2014 #2591 randerso Forced retrieval of combinations file
* Implemented retry on error
*
* </pre>
*
@ -78,6 +81,8 @@ public class CombinationsFileUtil {
private static final transient IUFStatusHandler statusHandler = UFStatus
.getHandler(CombinationsFileUtil.class);
private static final int MAX_TRIES = 2;
public static String COMBO_DIR_PATH = FileUtil.join("gfe", "combinations");
public static String SAVED_COMBO_DIR = FileUtil.join("gfe", "comboData");
@ -194,8 +199,8 @@ public class CombinationsFileUtil {
throws SerializationException {
LocalizationFile lf = idToFile(id);
File file = lf.getFile();
ComboData comboData = (ComboData) SerializationUtil
.jaxbUnmarshalFromXmlFile(file);
ComboData comboData = SerializationUtil.jaxbUnmarshalFromXmlFile(
ComboData.class, file);
Map<String, Integer> comboDict = new HashMap<String, Integer>(
comboData.combos.size());
@ -211,13 +216,20 @@ public class CombinationsFileUtil {
IPathManager pm = PathManagerFactory.getPathManager();
// 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);
}
LocalizationContext baseContext = pm.getContext(
LocalizationType.CAVE_STATIC, LocalizationLevel.BASE);
// Strip any path components from comboName
File comboFile = new File(comboName);
comboName = comboFile.getName();
String scriptPath = FileUtil.join(
GfePyIncludeUtil.getUtilitiesLF(baseContext).getFile()
.getPath(), "CombinationsInterface.py");
@ -226,19 +238,39 @@ public class CombinationsFileUtil {
HashMap<String, Object> map = new HashMap<String, Object>();
map.put("comboName", comboName);
PythonScript python = null;
try {
python = new PythonScript(scriptPath, PyUtil.buildJepIncludePath(
GfePyIncludeUtil.getCombinationsIncludePath(),
GfePyIncludeUtil.getCommonPythonIncludePath()),
CombinationsFileUtil.class.getClassLoader());
Object com = python.execute("getCombinations", map);
combos = (List<List<String>>) com;
} catch (JepException e) {
throw new GfeException("Error loading combinations file: "
+ comboName, e);
} finally {
if (python != null) {
python.dispose();
for (int retryCount = 0; retryCount < MAX_TRIES; retryCount++) {
try {
python = new PythonScript(scriptPath,
PyUtil.buildJepIncludePath(
GfePyIncludeUtil.getCombinationsIncludePath(),
GfePyIncludeUtil.getCommonPythonIncludePath()),
CombinationsFileUtil.class.getClassLoader());
Object com = python.execute("getCombinations", map);
combos = (List<List<String>>) com;
// if successfully retrieved break out of the loop
break;
} catch (JepException e) {
// remove the .pyo file
new File(pyFile.getAbsolutePath() + "o").delete();
// if not last try, log and try again
if (retryCount < MAX_TRIES - 1) {
// log but don't pop up
statusHandler.handle(Priority.EVENTB,
"Error loading combinations file: " + comboName
+ ", retrying ", e);
}
// else throw exception
else {
throw new GfeException("Error loading combinations file: "
+ comboName, e);
}
} finally {
if (python != null) {
python.dispose();
}
}
}
return combos;

View file

@ -19,8 +19,12 @@
**/
package com.raytheon.viz.gfe.vtec;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
@ -53,6 +57,7 @@ import com.raytheon.viz.texteditor.util.VtecUtil;
* Nov 22, 2013 #2578 dgilling Fix ETN assignment for products with
* multiple NEW VTEC lines for the same
* phensig but disjoint TimeRanges.
* Feb 05, 2014 #2774 dgilling Additional correction to previous fix.
*
* </pre>
*
@ -71,6 +76,19 @@ public class GFEVtecUtil {
public static final Collection<String> IGNORE_NATIONAL_ETN = ImmutableSet
.copyOf(GFEVtecConfig.getInstance().getSitesIgnoreNationalEtn());
private static final Comparator<TimeRange> TIME_COMPARATOR = new Comparator<TimeRange>() {
@Override
public int compare(TimeRange tr1, TimeRange tr2) {
int retVal = tr1.getStart().compareTo(tr2.getStart());
if (retVal == 0) {
retVal = tr1.getEnd().compareTo(tr2.getEnd());
}
return retVal;
}
};
/**
* A private constructor so that Java does not attempt to create one for us.
* As this class should not be instantiated, do not attempt to ever call
@ -101,7 +119,7 @@ public class GFEVtecUtil {
// 1. The first level is keyed by the hazard's phensig.
// 2. The second level is keyed by the valid period of the hazard.
// Effectively, making this a Map<Phensig, Map<ValidPeriod, ETN>>.
Map<String, Map<TimeRange, Integer>> etnCache = new HashMap<String, Map<TimeRange, Integer>>();
Map<String, Map<TimeRange, Integer>> etnCache = buildETNCache(message);
Matcher vtecMatcher = VtecUtil.VTEC_REGEX.matcher(message);
StringBuffer finalOutput = new StringBuffer();
@ -114,38 +132,10 @@ public class GFEVtecUtil {
&& ((!NATIONAL_PHENSIGS.contains(vtec.getPhensig())) || (IGNORE_NATIONAL_ETN
.contains(vtec.getOffice()) && TROPICAL_PHENSIGS
.contains(vtec.getPhensig())))) {
// Some more clarification on the ETN assignment behavior: all
// NEW VTEC lines with the same phensig should be assigned the
// same ETN if the hazards' valid periods are adjacent or
// overlapping.
// If there's a discontinuity in TimeRanges we increment to the
// next ETN.
Integer newEtn = null;
String phensig = vtec.getPhensig();
TimeRange validPeriod = new TimeRange(vtec.getStartTime()
.getTime(), vtec.getEndTime().getTime());
Map<TimeRange, Integer> etnsByTR = etnCache.get(phensig);
if (etnsByTR != null) {
for (TimeRange tr : etnsByTR.keySet()) {
if ((validPeriod.isAdjacentTo(tr))
|| (validPeriod.overlaps(tr))) {
newEtn = etnsByTR.get(tr);
break;
}
}
}
if (newEtn == null) {
newEtn = VtecUtil.getNextEtn(vtec.getOffice(),
vtec.getPhensig(), true);
}
Map<TimeRange, Integer> cacheLevel2 = (etnsByTR != null) ? etnsByTR
: new HashMap<TimeRange, Integer>();
cacheLevel2.put(validPeriod, newEtn);
etnCache.put(phensig, cacheLevel2);
Integer newEtn = etnCache.get(phensig).get(validPeriod);
vtec.setSequence(newEtn);
}
vtecMatcher
@ -157,4 +147,72 @@ public class GFEVtecUtil {
vtecMatcher.appendTail(finalOutput);
return finalOutput.toString();
}
private static Map<String, Map<TimeRange, Integer>> buildETNCache(
final String message) throws VizException {
Map<String, Map<TimeRange, Integer>> etnCache = new HashMap<String, Map<TimeRange, Integer>>();
String officeId = null;
Matcher vtecMatcher = VtecUtil.VTEC_REGEX.matcher(message);
while (vtecMatcher.find()) {
VtecObject vtec = new VtecObject(vtecMatcher.group());
officeId = vtec.getOffice();
if (("NEW".equals(vtec.getAction()))
&& ((!NATIONAL_PHENSIGS.contains(vtec.getPhensig())) || (IGNORE_NATIONAL_ETN
.contains(vtec.getOffice()) && TROPICAL_PHENSIGS
.contains(vtec.getPhensig())))) {
String phensig = vtec.getPhensig();
TimeRange validPeriod = new TimeRange(vtec.getStartTime()
.getTime(), vtec.getEndTime().getTime());
Map<TimeRange, Integer> etnsByTR = etnCache.get(phensig);
if (etnsByTR == null) {
etnsByTR = new HashMap<TimeRange, Integer>();
etnCache.put(phensig, etnsByTR);
}
etnsByTR.put(validPeriod, 0);
}
}
// With our first pass over the product text we have a list of all the
// NEW VTEC lines that need to have an ETN assigned to them. Depending
// on whether or not the time ranges of these lines overlap and the
// phensigs match, we might reuse ETNs for multiple VTEC lines.
for (String phensig : etnCache.keySet()) {
List<TimeRange> trList = new ArrayList<TimeRange>(etnCache.get(
phensig).keySet());
Collections.sort(trList, TIME_COMPARATOR);
for (int i = 0; i < trList.size(); i++) {
TimeRange validPeriod = trList.get(i);
Integer currentEtn = etnCache.get(phensig).get(validPeriod);
// the first time we select a new, unique ETN, any other VTEC
// lines in the product that have the same phensig and an
// adjacent TimeRange can also re-use this ETN
if (currentEtn == 0) {
currentEtn = VtecUtil.getNextEtn(officeId, phensig, true);
etnCache.get(phensig).put(validPeriod, currentEtn);
} else {
// BUT...once we've made our one pass through the product
// and re-used the ETN where appropriate, we should not
// check again
continue;
}
for (int j = i + 1; j < trList.size(); j++) {
TimeRange validPeriod2 = trList.get(j);
Integer currentEtn2 = etnCache.get(phensig).get(
validPeriod2);
if ((currentEtn2 == 0)
&& (validPeriod2.isAdjacentTo(validPeriod) || validPeriod2
.overlaps(validPeriod))) {
etnCache.get(phensig).put(validPeriod2, currentEtn);
}
}
}
}
return etnCache;
}
}

View file

@ -34,6 +34,7 @@ import com.raytheon.viz.hydrocommon.data.GageData.ThreatIndex;
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Nov 21, 2008 mpduff Initial creation
* Feb 03, 2014 16843 lbousaidi add a check for index OutOfBoundsException
*
* </pre>
*
@ -101,8 +102,9 @@ public class PDCFindBasis {
} else {
currentLid = fcstReportList.get(fcstIndex).getLid();
}
} else if (obsReportList.get(obsIndex) != null) {
currentLid = obsReportList.get(obsIndex).getLid();
} else if ((obsIndex< obsReportList.size()) && (obsReportList
.get(obsIndex) != null)) {
currentLid = obsReportList.get(obsIndex).getLid();
} else {
currentLid = fcstReportList.get(fcstIndex).getLid();
}

View file

@ -20,21 +20,23 @@
package com.raytheon.edex.plugin.gfe.server.handler;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.List;
import com.raytheon.edex.plugin.gfe.util.SendNotifications;
import com.raytheon.uf.common.dataplugin.gfe.request.SaveCombinationsFileRequest;
import com.raytheon.uf.common.dataplugin.gfe.server.message.ServerResponse;
import com.raytheon.uf.common.dataplugin.gfe.server.notify.CombinationsFileChangedNotification;
import com.raytheon.uf.common.localization.FileUpdatedMessage;
import com.raytheon.uf.common.localization.FileUpdatedMessage.FileChangeType;
import com.raytheon.uf.common.localization.IPathManager;
import com.raytheon.uf.common.localization.LocalizationContext;
import com.raytheon.uf.common.localization.LocalizationContext.LocalizationType;
import com.raytheon.uf.common.localization.LocalizationFile;
import com.raytheon.uf.common.localization.PathManagerFactory;
import com.raytheon.uf.common.serialization.comm.IRequestHandler;
import com.raytheon.uf.common.util.FileUtil;
@ -55,6 +57,7 @@ import com.raytheon.uf.edex.core.EDEXUtil;
* May 16, 2011 dgilling Initial creation
* Dec 02, 2013 #2591 dgilling Only send notification after Writer is
* flushed/closed.
* Feb 05, 2014 #2591 Added CombinationFileChangedNotification
*
* </pre>
*
@ -78,19 +81,22 @@ public class SaveCombinationsFileHandler implements
@Override
public ServerResponse<Object> handleRequest(
SaveCombinationsFileRequest request) throws Exception {
String siteID = request.getSiteID();
IPathManager pm = PathManagerFactory.getPathManager();
LocalizationContext localization = pm.getContextForSite(
LocalizationType.CAVE_STATIC, request.getSiteID());
LocalizationType.CAVE_STATIC, siteID);
File localFile = pm.getFile(localization,
FileUtil.join(COMBO_FILE_DIR, request.getFileName()));
boolean isAdded = (!localFile.exists());
String comboName = request.getFileName();
String fileName = FileUtil.join(COMBO_FILE_DIR, comboName) + ".py";
LocalizationFile lf = pm.getLocalizationFile(localization, fileName);
boolean isAdded = (!lf.exists());
Writer outWriter = null;
try {
outWriter = new BufferedWriter(new FileWriter(localFile));
outWriter = new BufferedWriter(new OutputStreamWriter(
lf.openOutputStream()));
String zoneComments = "\n# Automatically generated combinations file\n# "
+ request.getFileName() + "\n\nCombinations = [\n";
+ comboName + "\n\nCombinations = [\n";
outWriter.write(zoneComments);
NumberFormat df = new DecimalFormat("00");
@ -115,20 +121,25 @@ public class SaveCombinationsFileHandler implements
outWriter.close();
}
}
lf.save();
// placing the notification code here ensures we only send the
// notification on a successful file write operation. Otherwise we would
// have thrown an IOException and never gotten to this portion of the
// request handler.
// TODO: remove sending of FileUpdateMessage after DR #2768 is fixed
FileChangeType changeType = isAdded ? FileChangeType.ADDED
: FileChangeType.UPDATED;
EDEXUtil.getMessageProducer().sendAsync(
"utilityNotify",
new FileUpdatedMessage(localization, FileUtil.join(
COMBO_FILE_DIR, request.getFileName()), changeType,
localFile.lastModified()));
new FileUpdatedMessage(localization, fileName, changeType, lf
.getTimeStamp().getTime()));
CombinationsFileChangedNotification notif = new CombinationsFileChangedNotification(
comboName, request.getWorkstationID(), siteID);
SendNotifications.send(notif);
return new ServerResponse<Object>();
}
}

View file

@ -84,7 +84,7 @@ from com.raytheon.uf.edex.database.cluster import ClusterTask
# 11/05/13 2517 randerso Restructured logging so it coulde be used by WECache
# Changed WECache to limit the number of cached grids kept in memory
# 01/09/14 16952 randerso Fix regression made in #2517 which caused errors with overlapping grids
#
# 02/04/14 17042 ryu Check in changes for randerso.
#
BATCH_DELAY = 0.0
@ -1531,7 +1531,7 @@ class IscMosaic:
smsg, oldEntry, keyentry, ",".join(changedReasons))
msg = "%s %s %s [%s] -> [%s] (%s)" % \
self.__siteID, parmName, printShortTR(tr), oldEntry, keyentry, ",".join(changedReasons)
(self.__siteID, parmName, printShortTR(tr), oldEntry, keyentry, ",".join(changedReasons))
self.__adjDataMsg.append(msg)
key[idx] = keyentry #store back into list
@ -1631,7 +1631,7 @@ class IscMosaic:
smsg, oldEntry, keyentry, ",".join(changedReasons))
msg = "%s %s %s [%s] -> [%s] (%s)" % \
self.__siteID, parmName, printShortTR(tr), oldEntry, keyentry, ",".join(changedReasons)
(self.__siteID, parmName, printShortTR(tr), oldEntry, keyentry, ",".join(changedReasons))
self.__adjDataMsg.append(msg)

View file

@ -0,0 +1,83 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.uf.common.dataplugin.gfe.server.notify;
import com.raytheon.uf.common.message.WsId;
import com.raytheon.uf.common.serialization.annotations.DynamicSerialize;
import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement;
/**
* Combinations File Changed Notification
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Feb 5, 2014 #2591 randerso Initial creation
*
* </pre>
*
* @author randerso
* @version 1.0
*/
@DynamicSerialize
public class CombinationsFileChangedNotification extends GfeNotification {
@DynamicSerializeElement
private String combinationsFileName;
@DynamicSerializeElement
private WsId whoChanged;
/**
* default constructor for serialization
*/
public CombinationsFileChangedNotification() {
super();
}
public CombinationsFileChangedNotification(String combinationsFileName,
WsId whoChanged, String siteID) {
super();
this.siteID = siteID;
this.combinationsFileName = combinationsFileName;
this.whoChanged = whoChanged;
}
public String getCombinationsFileName() {
return combinationsFileName;
}
public void setCombinationsFileName(String combinationsFileName) {
this.combinationsFileName = combinationsFileName;
}
public WsId getWhoChanged() {
return whoChanged;
}
public void setWhoChanged(WsId whoChanged) {
this.whoChanged = whoChanged;
}
}

View file

@ -76,6 +76,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.
* </pre>
*
* @author rjpeter
@ -665,8 +666,11 @@ public class DatabaseArchiveProcessor<T extends PersistableDataObject<?>>
Iterator<PersistableDataObject<?>> pdoIter = pdos.iterator();
writer = new BufferedWriter(new FileWriter(dumpFile));
statusHandler.info(String.format("%s: Dumping records to: %s",
pluginName, dumpFile.getAbsolutePath()));
if (statusHandler.isPriorityEnabled(Priority.INFO)) {
statusHandler.info(String.format("%s: Dumping records to: %s",
pluginName, dumpFile.getAbsolutePath()));
}
while (pdoIter.hasNext()) {
PersistableDataObject<?> pdo = pdoIter.next();
@ -676,9 +680,11 @@ public class DatabaseArchiveProcessor<T extends PersistableDataObject<?>>
// otherwise was read from file and will be recorded in
// a previous entry
writer.write("" + pluginDataObject.getId() + ":");
writer.write(pluginDataObject.getDataURI());
writer.write("\n");
} else {
writer.write("-:");
}
writer.write(pluginDataObject.getDataURI());
writer.write("\n");
} else {
writer.write(pdo.getIdentifier().toString());
writer.write("\n");

View file

@ -5,7 +5,7 @@
Name: awips2-ant
Summary: AWIPS II Ant Distribution
Version: 1.7.1
Release: 2
Release: 3
Group: AWIPSII
BuildRoot: %{_build_root}
BuildArch: noarch

View file

@ -8,10 +8,7 @@ if [ ${RC} -ne 0 ]; then
fi
# Determine Where Ant Has Been Installed.
ANT_INSTALL=`rpm -q --queryformat '%{INSTALLPREFIX}' awips2-ant`
if [ "${ANT_INSTALL}" = "" ]; then
return
fi
ANT_INSTALL=/awips2/ant
# Update The Environment.
export ANT_HOME="${ANT_INSTALL}"

View file

@ -410,7 +410,8 @@ fi
if [ "${1}" = "-viz" ]; then
buildRPM "awips2"
buildRPM "awips2-common-base"
buildRPM "awips2-python-numpy"
#buildRPM "awips2-python-numpy"
buildRPM "awips2-ant"
#buildRPM "awips2-python-dynamicserialize"
#buildRPM "awips2-python"
#buildRPM "awips2-adapt-native"
@ -421,9 +422,9 @@ if [ "${1}" = "-viz" ]; then
#buildRPM "awips2-httpd-pypies"
#buildRPM "awips2-hydroapps-shared"
#buildRPM "awips2-rcm"
buildRPM "awips2-gfesuite-client"
buildRPM "awips2-gfesuite-server"
buildRPM "awips2-tools"
#buildRPM "awips2-gfesuite-client"
#buildRPM "awips2-gfesuite-server"
#buildRPM "awips2-tools"
#buildRPM "awips2-cli"
buildCAVE
if [ $? -ne 0 ]; then