Issue #1759: Convert ifpnetCDF and iscMosaic to use more robust request

implementations, convert request handlers to use new python concurrent
framework, excise GfeScript and GfeScriptExecutor from the system.

Change-Id: I801b7b9812a72fdfc72975a311d8dc3806cda152

Former-commit-id: edaef1edf93ed7d7f626591ecfd86fb4c76f92e8
This commit is contained in:
David Gillingham 2013-03-11 12:53:14 -05:00
parent 729bc9c4bb
commit 7c74510723
32 changed files with 2053 additions and 1339 deletions

View file

@ -34,6 +34,8 @@ from collections import OrderedDict
# Date Ticket# Engineer Description
# ------------ ---------- ----------- --------------------------
# 05/01/08 njensen Initial Creation.
# 03/12/13 1759 dgilling Extend Java List types handled
# by javaObjToPyVal().
#
#
#
@ -133,7 +135,7 @@ def javaObjToPyVal(obj, customConverter=None):
retVal = obj.longValue()
elif objtype == "java.lang.Boolean":
retVal = bool(obj.booleanValue())
elif objtype == "java.util.ArrayList":
elif objtype in ["java.util.ArrayList", "java.util.Arrays$ArrayList"]:
retVal = []
size = obj.size()
for i in range(size):

View file

@ -27,7 +27,8 @@ Require-Bundle: com.raytheon.uf.common.dataplugin.gfe;bundle-version="1.12.1174"
com.raytheon.uf.common.parameter;bundle-version="1.0.0",
com.raytheon.uf.common.dataplugin.grid;bundle-version="1.0.0",
com.raytheon.uf.common.util;bundle-version="1.12.1174",
com.google.guava;bundle-version="1.0.0"
com.google.guava;bundle-version="1.0.0",
com.raytheon.uf.common.python.concurrent;bundle-version="1.0.0"
Export-Package: com.raytheon.edex.plugin.gfe,
com.raytheon.edex.plugin.gfe.config,
com.raytheon.edex.plugin.gfe.db.dao,

View file

@ -54,7 +54,9 @@
<constructor-arg ref="dbInventoryHandler" />
</bean>
<bean id="executeIscMosaicHandler"
class="com.raytheon.edex.plugin.gfe.server.handler.ExecuteIscMosaicRequestHandler" />
class="com.raytheon.edex.plugin.gfe.server.handler.ExecuteIscMosaicRequestHandler">
<constructor-arg ref="iscMosaicPythonThreadPool" />
</bean>
<bean factory-bean="handlerRegistry" factory-method="register">
<constructor-arg
value="com.raytheon.uf.common.dataplugin.gfe.request.ExecuteIscMosaicRequest" />
@ -131,10 +133,12 @@
<constructor-arg ref="lockTablesHandler" />
</bean>
<bean id="netCDFHandler"
class="com.raytheon.edex.plugin.gfe.server.handler.CreateNetCDFGridRequestHandler" />
class="com.raytheon.edex.plugin.gfe.server.handler.ExecuteIfpNetCDFGridRequestHandler">
<constructor-arg ref="ifpnetCDFPythonThreadPool" />
</bean>
<bean factory-bean="handlerRegistry" factory-method="register">
<constructor-arg
value="com.raytheon.uf.common.dataplugin.gfe.request.CreateNetCDFGridRequest" />
value="com.raytheon.uf.common.dataplugin.gfe.request.ExecuteIfpNetCDFGridRequest" />
<constructor-arg ref="netCDFHandler" />
</bean>
<bean id="purgeGfeGridsHandler"
@ -481,8 +485,59 @@
<property name="corePoolSize" value="2" />
<property name="maxPoolSize" value="2" />
</bean>
<bean id="IscReceiveSrv" class="com.raytheon.edex.plugin.gfe.isc.IscReceiveSrv" />
<bean id="IscReceiveSrv" class="com.raytheon.edex.plugin.gfe.isc.IscReceiveSrv">
<constructor-arg ref="iscDataRecPythonThreadPool" />
</bean>
<!-- End ISC Receive Beans -->
<!-- Additional ISC Beans -->
<bean id="ifpnetCDFFactory" class="com.raytheon.edex.plugin.gfe.isc.IscScriptFactory">
<constructor-arg value="ifpnetCDF" />
<constructor-arg value="2" />
</bean>
<bean name="ifpnetCDFPythonThreadPool"
class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="staticMethod"
value="com.raytheon.uf.common.python.concurrent.PythonJobCoordinator.newInstance" />
<property name="arguments">
<list>
<ref bean="ifpnetCDFFactory" />
</list>
</property>
</bean>
<bean id="iscMosaicFactory" class="com.raytheon.edex.plugin.gfe.isc.IscScriptFactory">
<constructor-arg value="iscMosaic" />
<constructor-arg value="2" />
</bean>
<bean name="iscMosaicPythonThreadPool"
class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="staticMethod"
value="com.raytheon.uf.common.python.concurrent.PythonJobCoordinator.newInstance" />
<property name="arguments">
<list>
<ref bean="iscMosaicFactory" />
</list>
</property>
</bean>
<bean id="iscDataRecFactory" class="com.raytheon.edex.plugin.gfe.isc.IscScriptFactory">
<constructor-arg value="iscDataRec" />
<constructor-arg value="2" />
</bean>
<bean name="iscDataRecPythonThreadPool"
class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="staticMethod"
value="com.raytheon.uf.common.python.concurrent.PythonJobCoordinator.newInstance" />
<property name="arguments">
<list>
<ref bean="iscDataRecFactory" />
</list>
</property>
</bean>
<!-- End Additional ISC Beans -->
<bean id="logPurger" class="com.raytheon.edex.plugin.gfe.log.LogPurger" />

View file

@ -1,204 +0,0 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.edex.plugin.gfe.isc;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import jep.JepException;
import com.raytheon.uf.common.dataplugin.gfe.python.GfePyIncludeUtil;
import com.raytheon.uf.common.localization.IPathManager;
import com.raytheon.uf.common.localization.LocalizationContext;
import com.raytheon.uf.common.localization.LocalizationContext.LocalizationLevel;
import com.raytheon.uf.common.localization.LocalizationContext.LocalizationType;
import com.raytheon.uf.common.localization.PathManagerFactory;
import com.raytheon.uf.common.python.PyUtil;
import com.raytheon.uf.common.python.PythonScript;
/**
* Thread object which contains a script to execute.
*
* <pre>
*
* SOFTWARE HISTORY
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Oct 23, 2009 #2960 bphillip Initial creation
* Mar 04, 2013 #1447 dgilling Add VTEC scripts to include path.
*
* </pre>
*
* @author bphillip
* @version 1.0
*/
public class GfeScript extends Thread {
/** The site this script is to be run for */
private String site;
/** The name of the script to execute */
private String scriptName;
/** The method name to execute. Defaults to "main" */
private String methodName = "main";
private String pythonIncludePath;
/** The PythonScript instance */
private PythonScript script;
/** The return value returned from the last execution */
private String retVal;
private boolean running = false;
private BlockingQueue<Map<String, Object>> cmdQueue = new LinkedBlockingQueue<Map<String, Object>>();
/**
* Creates a new GfeScript for a specific script
*
* @param scriptName
* The name of the script
*/
public GfeScript(String scriptName, String site) {
setDaemon(true);
this.scriptName = scriptName;
this.site = site;
}
@Override
public void run() {
/*
* Loads a script from the localization directory
*/
IPathManager pathMgr = PathManagerFactory.getPathManager();
LocalizationContext cx = pathMgr.getContext(
LocalizationType.EDEX_STATIC, LocalizationLevel.BASE);
String scriptFile = pathMgr
.getLocalizationFile(cx,
"gfe/isc" + File.separator + scriptName + ".py")
.getFile().getPath();
// Instantiates the PythonScript if necessary
try {
if (pythonIncludePath == null) {
pythonIncludePath = PyUtil.buildJepIncludePath(
GfePyIncludeUtil.getCommonPythonIncludePath(),
GfePyIncludeUtil.getVtecIncludePath(site),
GfePyIncludeUtil.getIscScriptsIncludePath(),
GfePyIncludeUtil.getGfeConfigIncludePath(site));
}
script = new PythonScript(scriptFile, pythonIncludePath);
} catch (JepException e1) {
retVal = e1.getMessage();
return;
}
/*
* Infinite loop which waits until notified to execute the script
*/
try {
while (true) {
try {
this.running = false;
script.execute(methodName, getNextCommand());
} catch (InterruptedException e) {
retVal = e.getLocalizedMessage();
continue;
} catch (JepException e) {
retVal = e.getLocalizedMessage();
continue;
} catch (Throwable e) {
retVal = e.getLocalizedMessage();
continue;
}
retVal = "Success";
}
} finally {
if (script != null) {
script.dispose();
}
}
}
public Map<String, Object> getNextCommand() throws InterruptedException {
Map<String, Object> retVal = cmdQueue.take();
this.running = true;
return retVal;
}
/**
* Executes the script
*
* @param args
* The arguments to pass to the script
*/
public void execute(String[] args) {
this.running = true;
cmdQueue.add(setArguments(args));
}
public void execute(String method, Map<String, Object> args) {
this.running = true;
this.methodName = method;
cmdQueue.add(args);
}
/**
* Gets the return value of the last execution
*
* @return The return value of the las execution
*/
public String getRetVal() {
return retVal;
}
private Map<String, Object> setArguments(String[] args) {
Map<String, Object> argMap = new HashMap<String, Object>();
List<String> argList = new ArrayList<String>();
argList.add(scriptName);
argList.addAll(Arrays.asList(args));
argMap.put("argv", argList);
return argMap;
}
public boolean isRunning() {
return running;
}
public String waitFor() {
try {
while (isRunning()) {
Thread.sleep(200);
}
} catch (InterruptedException e1) {
}
return retVal;
}
}

View file

@ -1,336 +0,0 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.edex.plugin.gfe.isc;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import com.raytheon.edex.plugin.gfe.config.IFPServerConfigManager;
import com.raytheon.edex.plugin.gfe.exception.GfeConfigurationException;
import com.raytheon.edex.site.SiteUtil;
import com.raytheon.uf.common.status.IUFStatusHandler;
import com.raytheon.uf.common.status.UFStatus;
import com.raytheon.uf.common.util.FileUtil;
import com.raytheon.uf.edex.site.SiteAwareRegistry;
/**
* Executes gfe related python Scripts
*
* <pre>
*
* SOFTWARE HISTORY
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Oct 9, 2009 bphillip Initial creation
*
* </pre>
*
* @author bphillip
* @version 1.0
*/
public class GfeScriptExecutor {
private static final transient IUFStatusHandler statusHandler = UFStatus
.getHandler(GfeScriptExecutor.class);
public static final String SUCCESS = "Success";
private static Map<String, GfeScript> scriptMap = new ConcurrentHashMap<String, GfeScript>();
private static final FilenameFilter docFileFilter = new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
return name.endsWith(".doc");
}
};
/**
* Creates a new GfeScriptExecutor
*/
public GfeScriptExecutor() {
}
/**
* Executes a command
*
* @param command
* The command to execute
* @return Null on success, else returns the exception message
*/
public String execute(String command) {
String retVal = SUCCESS;
String[] argv = command.trim().split(" ");
String[] arguments = new String[argv.length - 1];
String scriptName = argv[0];
System.arraycopy(argv, 1, arguments, 0, arguments.length);
Map<String, String[]> sites = null;
try {
sites = getSite(scriptName, arguments);
} catch (IOException e) {
return "Error getting sites for script\n" + e.getMessage();
} catch (InterruptedException e) {
return "Error copying received ISC file\n" + e.getMessage();
} catch (GfeConfigurationException e) {
return "Error getting database configuration\n" + e.getMessage();
}
for (String site : sites.keySet()) {
GfeScript theScript = null;
String key = scriptName + site;
// synchronize on the map here so multiple threads don't try
// creating the same GfeScript object
synchronized (scriptMap) {
theScript = scriptMap.get(key);
if (theScript == null) {
theScript = new GfeScript(scriptName, site);
theScript.start();
scriptMap.put(key, theScript);
}
}
String scriptRetVal = null;
// synchronize on the GfeScript object here so multiple threads
// can't try to execute the same instance at once
synchronized (theScript) {
theScript.execute(sites.get(site));
scriptRetVal = theScript.waitFor();
}
if (!scriptRetVal.equals(SUCCESS)) {
if (retVal.equals(SUCCESS)) {
retVal = scriptRetVal;
} else {
retVal += scriptRetVal;
}
statusHandler.error(scriptName + " failed for site " + site);
}
}
return retVal;
}
private static Map<String, String[]> getSite(String scriptName,
String[] args) throws IOException, InterruptedException,
GfeConfigurationException {
List<String> siteList = new ArrayList<String>();
Map<String, String[]> siteMap = new HashMap<String, String[]>();
if (scriptName.equals("iscDataRec")) {
String[] tokens = args[2].split(",");
String xmlFileName = "";
String dataFileName = null;
if (tokens.length == 1) {
xmlFileName = tokens[0];
} else {
dataFileName = tokens[0];
xmlFileName = tokens[1];
}
String fileContents = getFileContents(xmlFileName);
Pattern pat = Pattern.compile("<site>(.*?)</site>");
Matcher matcher = pat.matcher(fileContents);
while (matcher.find()) {
siteList.add(matcher.group(1));
}
List<String> activeSites = Arrays.asList(SiteAwareRegistry
.getInstance().getActiveSites());
if (fileContents.contains("<iscrequest>")) {
// Need to copy the request file if more than 1 site is active
// on this EDEX server. Otherwise, the file will be deleted
// after the first site has processed the request file
siteList.remove(siteList.size() - 1);
for (int i = 0; i < siteList.size(); i++) {
if (activeSites.contains(siteList.get(i))) {
if (IFPServerConfigManager.getServerConfig(
siteList.get(i)).requestISC()) {
String[] newArgs = new String[args.length];
System.arraycopy(args, 0, newArgs, 0, args.length);
String newXmlFileName = copyFile(xmlFileName,
siteList.get(i));
newArgs[2] = newXmlFileName;
siteMap.put(siteList.get(i), newArgs);
}
}
}
new File(xmlFileName).delete();
} else {
// Remove the source site
siteList.remove(0);
Set<String> siteSet = new HashSet<String>();
siteSet.addAll(siteList);
try {
for (String site : siteSet) {
if (activeSites.contains(site)
&& IFPServerConfigManager.getServerConfig(site)
.requestISC()) {
String newFileName = null;
String newXmlFileName = null;
try {
newFileName = copyFile(dataFileName, site);
newXmlFileName = copyFile(xmlFileName, site);
} catch (IOException e) {
statusHandler
.error("Failed to copy: ["
+ dataFileName
+ "] to "
+ newFileName
+ ". Unable to execute iscDataRec for "
+ site, e);
continue;
}
if (!new File(newFileName).exists()) {
statusHandler
.error("Failed to copy: ["
+ dataFileName
+ "] to "
+ newFileName
+ ". Unable to execute iscDataRec for "
+ site);
continue;
}
if (!new File(newXmlFileName).exists()) {
statusHandler
.error("Failed to copy: ["
+ xmlFileName
+ "] to "
+ newXmlFileName
+ ". Unable to execute iscDataRec for "
+ site);
continue;
}
String[] modifiedArgs = new String[args.length];
System.arraycopy(args, 0, modifiedArgs, 0,
args.length);
modifiedArgs[2] = modifiedArgs[2].replace(
dataFileName, newFileName);
modifiedArgs[2] = modifiedArgs[2].replace(
xmlFileName, newXmlFileName);
siteMap.put(site, modifiedArgs);
}
}
} finally {
File dataFile = new File(dataFileName);
File xmlFile = new File(xmlFileName);
if (dataFile.exists()) {
if (!dataFile.delete()) {
statusHandler.error("Unable to delete "
+ dataFileName);
}
}
if (xmlFile.exists()) {
if (!xmlFile.delete()) {
statusHandler.error("Unable to delete "
+ xmlFileName);
}
}
ArrayList<File> docFiles = FileUtil.listFiles(
xmlFile.getParentFile(), docFileFilter, false);
for (File docFile : docFiles) {
docFile.delete();
}
}
}
} else {
siteMap.put(SiteUtil.getSite(), args);
}
return siteMap;
}
private static String getFileContents(String file) throws IOException {
BufferedReader in = null;
String fileContents = "";
try {
in = new BufferedReader(new FileReader(file));
String line = null;
while ((line = in.readLine()) != null) {
fileContents += line;
}
} finally {
if (in != null) {
in.close();
}
}
return fileContents;
}
private static String copyFile(String src, String site) throws IOException {
String dst = src + "." + site;
InputStream in = null;
OutputStream out = null;
try {
in = new FileInputStream(src);
out = new FileOutputStream(dst);
// Transfer bytes from in to out
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
statusHandler
.error("Error closing input stream while copying isc file!",
e);
}
}
if (out != null) {
try {
out.close();
} catch (IOException e) {
statusHandler
.error("Error closing file output stream while copying isc file!",
e);
}
}
}
return dst;
}
}

View file

@ -19,9 +19,31 @@
**/
package com.raytheon.edex.plugin.gfe.isc;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import com.raytheon.edex.plugin.gfe.config.IFPServerConfigManager;
import com.raytheon.edex.plugin.gfe.exception.GfeConfigurationException;
import com.raytheon.uf.common.dataplugin.gfe.request.IscDataRecRequest;
import com.raytheon.uf.common.python.concurrent.IPythonJobListener;
import com.raytheon.uf.common.python.concurrent.PythonJobCoordinator;
import com.raytheon.uf.common.status.IUFStatusHandler;
import com.raytheon.uf.common.status.UFStatus;
import com.raytheon.uf.common.status.UFStatus.Priority;
import com.raytheon.uf.common.util.FileUtil;
import com.raytheon.uf.edex.site.SiteAwareRegistry;
/**
* ISC data receive service. Takes incoming request and executes iscDataRec
@ -33,7 +55,8 @@ import com.raytheon.uf.common.status.UFStatus;
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Mar 5, 2012 #361 dgilling Initial creation
* Mar 05, 2012 #361 dgilling Initial creation
* Mar 12, 2013 #1759 dgilling Re-implement using IscScript.
*
* </pre>
*
@ -45,13 +68,195 @@ public class IscReceiveSrv {
private static final transient IUFStatusHandler statusHandler = UFStatus
.getHandler(IscReceiveSrv.class);
public static void processRequest(IscDataRecRequest request) {
GfeScriptExecutor scriptRunner = new GfeScriptExecutor();
String retVal = scriptRunner.execute("iscDataRec "
+ request.getArgString());
if (!retVal.equals(GfeScriptExecutor.SUCCESS)) {
statusHandler.error("Error encountered executing iscDataRec: "
+ retVal);
private static final String METHOD_NAME = "main";
private static final FilenameFilter docFileFilter = new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
return name.endsWith(".doc");
}
};
private static final IPythonJobListener<String> jobListener = new IPythonJobListener<String>() {
@Override
public void jobFinished(String result) {
if (result != null) {
statusHandler.error("Error encountered executing iscDataRec: "
+ result);
}
}
@Override
public void jobFailed(Throwable e) {
statusHandler.error("Error encountered executing iscDataRec: ", e);
}
};
private final PythonJobCoordinator<IscScript> threadPool;
public IscReceiveSrv(PythonJobCoordinator<IscScript> threadPool) {
this.threadPool = threadPool;
}
public void processRequest(IscDataRecRequest request) {
String[] origArgs = request.getArgString().trim().split(" ");
Map<String, String[]> siteArgMap = Collections.emptyMap();
try {
siteArgMap = prepareIscDataRec(origArgs);
} catch (IOException e) {
statusHandler.error("Error reading received XML file", e);
return;
} catch (InterruptedException e) {
statusHandler.error("Error copying received ISC file", e);
return;
} catch (GfeConfigurationException e) {
statusHandler.error("Error getting GFE configuration", e);
return;
}
for (Entry<String, String[]> siteArgs : siteArgMap.entrySet()) {
Map<String, Object> args = new HashMap<String, Object>();
args.put("argv", Arrays.asList(siteArgs.getValue()));
IscScriptExecutor executor = new IscScriptExecutor(METHOD_NAME,
siteArgs.getKey(), args);
try {
threadPool.submitAsyncJob(executor, jobListener);
} catch (Exception e) {
statusHandler
.handle(Priority.PROBLEM,
"Could not submit execution job to Python thread pool for iscDataRec",
e);
}
}
}
private Map<String, String[]> prepareIscDataRec(String[] args)
throws IOException, InterruptedException, GfeConfigurationException {
Map<String, String[]> siteMap = new HashMap<String, String[]>();
String[] incomingFiles = args[2].split(",");
String xmlFileName = "";
String dataFileName = null;
if (incomingFiles.length == 1) {
xmlFileName = incomingFiles[0];
} else {
dataFileName = incomingFiles[0];
xmlFileName = incomingFiles[1];
}
final File incomingXMLFile = new File(xmlFileName);
String fileContents = FileUtil.file2String(incomingXMLFile);
Pattern siteTagRegEx = Pattern.compile("<site>(.*?)</site>");
Matcher matcher = siteTagRegEx.matcher(fileContents);
List<String> siteList = new ArrayList<String>();
while (matcher.find()) {
siteList.add(matcher.group(1));
}
List<String> activeSites = Arrays.asList(SiteAwareRegistry
.getInstance().getActiveSites());
if (fileContents.contains("<iscrequest>")) {
// Need to copy the request file if more than 1 site is active
// on this EDEX server. Otherwise, the file will be deleted
// after the first site has processed the request file
siteList.remove(siteList.size() - 1);
for (int i = 0; i < siteList.size(); i++) {
final String siteId = siteList.get(i);
if (activeSites.contains(siteId)) {
if (IFPServerConfigManager.getServerConfig(siteId)
.requestISC()) {
String[] newArgs = new String[args.length];
System.arraycopy(args, 0, newArgs, 0, args.length);
String newXmlFileName = xmlFileName + "." + siteId;
FileUtil.copyFile(incomingXMLFile, new File(
newXmlFileName));
newArgs[2] = newXmlFileName;
siteMap.put(siteId, newArgs);
}
}
}
incomingXMLFile.delete();
} else {
// Remove the source site
siteList.remove(0);
Set<String> siteSet = new HashSet<String>(siteList);
try {
for (String site : siteSet) {
if (activeSites.contains(site)
&& IFPServerConfigManager.getServerConfig(site)
.requestISC()) {
String newFileName = dataFileName + "." + site;
String newXmlFileName = xmlFileName + "." + site;
try {
FileUtil.copyFile(new File(dataFileName), new File(
newFileName));
} catch (IOException e) {
statusHandler.error("Failed to copy: ["
+ dataFileName + "] to " + newFileName
+ ". Unable to execute iscDataRec for "
+ site, e);
continue;
}
try {
FileUtil.copyFile(new File(xmlFileName), new File(
newXmlFileName));
} catch (IOException e) {
statusHandler.error("Failed to copy: ["
+ xmlFileName + "] to " + newXmlFileName
+ ". Unable to execute iscDataRec for "
+ site, e);
continue;
}
if (!new File(newFileName).exists()) {
statusHandler.error("Failed to copy: ["
+ dataFileName + "] to " + newFileName
+ ". Unable to execute iscDataRec for "
+ site);
continue;
}
if (!new File(newXmlFileName).exists()) {
statusHandler.error("Failed to copy: ["
+ xmlFileName + "] to " + newXmlFileName
+ ". Unable to execute iscDataRec for "
+ site);
continue;
}
String[] modifiedArgs = new String[args.length];
System.arraycopy(args, 0, modifiedArgs, 0, args.length);
modifiedArgs[2] = modifiedArgs[2].replace(dataFileName,
newFileName);
modifiedArgs[2] = modifiedArgs[2].replace(xmlFileName,
newXmlFileName);
siteMap.put(site, modifiedArgs);
}
}
} finally {
File dataFile = new File(dataFileName);
File xmlFile = incomingXMLFile;
if (dataFile.exists()) {
if (!dataFile.delete()) {
statusHandler.error("Unable to delete " + dataFileName);
}
}
if (xmlFile.exists()) {
if (!xmlFile.delete()) {
statusHandler.error("Unable to delete " + xmlFileName);
}
}
ArrayList<File> docFiles = FileUtil.listFiles(
xmlFile.getParentFile(), docFileFilter, false);
for (File docFile : docFiles) {
docFile.delete();
}
}
}
return siteMap;
}
}

View file

@ -0,0 +1,152 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.edex.plugin.gfe.isc;
import java.io.File;
import java.util.Map;
import jep.JepException;
import com.raytheon.uf.common.dataplugin.gfe.python.GfePyIncludeUtil;
import com.raytheon.uf.common.localization.IPathManager;
import com.raytheon.uf.common.localization.LocalizationContext;
import com.raytheon.uf.common.localization.LocalizationContext.LocalizationLevel;
import com.raytheon.uf.common.localization.LocalizationContext.LocalizationType;
import com.raytheon.uf.common.localization.PathManagerFactory;
import com.raytheon.uf.common.python.PyUtil;
import com.raytheon.uf.common.python.PythonScript;
import com.raytheon.uf.common.util.FileUtil;
/**
* PythonScript object to run a GFE ISC script, like ifpnetCDF or iscDataRec.
* This object's special feature is that it adds site-specific config paths to
* the python include path before each execution.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Mar 11, 2013 dgilling Initial creation
*
* </pre>
*
* @author dgilling
* @version 1.0
*/
public class IscScript extends PythonScript {
private static final String FILEDIR = GfePyIncludeUtil.ISC;
private final String scriptName;
public IscScript(String scriptName) throws JepException {
super(buildFilePath(scriptName), buildIncludePath(), IscScript.class
.getClassLoader());
jep.eval("import RollBackImporter");
jep.eval("rollbackImporter = RollBackImporter.RollBackImporter()");
this.scriptName = scriptName;
}
private static String buildFilePath(String scriptName) {
IPathManager pathMgr = PathManagerFactory.getPathManager();
LocalizationContext ctx = pathMgr.getContext(
LocalizationType.EDEX_STATIC, LocalizationLevel.BASE);
File file = pathMgr.getFile(ctx, FileUtil.join(FILEDIR, scriptName));
return file.getPath();
}
private static String buildIncludePath() {
return PyUtil.buildJepIncludePath(
GfePyIncludeUtil.getCommonPythonIncludePath(),
GfePyIncludeUtil.getIscScriptsIncludePath());
}
public Object execute(String methodName, Map<String, Object> args,
String siteId) throws JepException {
addSiteSpecificInclude(siteId);
Object retVal = super.execute(methodName, args);
jep.eval("rollbackImporter.rollback()");
removeSiteSpecificInclude(siteId);
return retVal;
}
public String getScriptName() {
return scriptName;
}
private void addSiteSpecificInclude(String siteId) throws JepException {
IPathManager pathMgr = PathManagerFactory.getPathManager();
// first we'll add config, then VTEC
LocalizationContext baseCtx = pathMgr.getContext(
LocalizationType.EDEX_STATIC, LocalizationLevel.BASE);
String basePath = GfePyIncludeUtil.getGfeConfigLF(baseCtx).getFile()
.getPath();
LocalizationContext siteCtx = pathMgr.getContextForSite(
LocalizationType.EDEX_STATIC, siteId);
String sitePath = GfePyIncludeUtil.getGfeConfigLF(siteCtx).getFile()
.getPath();
addSitePath(sitePath, basePath);
baseCtx = pathMgr.getContext(LocalizationType.COMMON_STATIC,
LocalizationLevel.BASE);
basePath = GfePyIncludeUtil.getVtecLF(baseCtx).getFile().getPath();
siteCtx = pathMgr.getContextForSite(LocalizationType.COMMON_STATIC,
siteId);
sitePath = GfePyIncludeUtil.getVtecLF(siteCtx).getFile().getPath();
addSitePath(sitePath, basePath);
}
private void addSitePath(String sitePath, String basePath)
throws JepException {
boolean inList = (Boolean) jep.getValue("'" + basePath
+ "' in sys.path");
int index;
if (inList) {
index = (Integer) jep
.getValue("sys.path.index('" + basePath + "')");
} else {
index = (Integer) jep.getValue("len(sys.path)");
}
jep.eval("sys.path.insert(" + index + ", '" + sitePath + "')");
}
private void removeSiteSpecificInclude(String siteId) throws JepException {
IPathManager pathMgr = PathManagerFactory.getPathManager();
// remove in reverse order
LocalizationContext siteCtx = pathMgr.getContextForSite(
LocalizationType.COMMON_STATIC, siteId);
String path = GfePyIncludeUtil.getVtecLF(siteCtx).getFile().getPath();
removeSitePath(path);
siteCtx = pathMgr.getContextForSite(LocalizationType.EDEX_STATIC,
siteId);
path = GfePyIncludeUtil.getGfeConfigLF(siteCtx).getFile().getPath();
removeSitePath(path);
}
private void removeSitePath(String path) throws JepException {
jep.eval("sys.path.remove('" + path + "')");
}
}

View file

@ -0,0 +1,93 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.edex.plugin.gfe.isc;
import java.util.Map;
import jep.JepException;
import com.raytheon.uf.common.python.concurrent.IPythonExecutor;
import com.raytheon.uf.common.status.IUFStatusHandler;
import com.raytheon.uf.common.status.UFStatus;
import com.raytheon.uf.common.status.UFStatus.Priority;
/**
* {@link IPythonExecutor} class for {@link IscScript} that runs an execute
* method in the script using the ExecutorService.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Mar 11, 2013 dgilling Initial creation
*
* </pre>
*
* @author dgilling
* @version 1.0
*/
public class IscScriptExecutor implements IPythonExecutor<IscScript, String> {
private static final IUFStatusHandler statusHandler = UFStatus
.getHandler(IscScriptExecutor.class);
private String methodName;
private String siteId;
private Map<String, Object> args;
public IscScriptExecutor(String methodName, String siteId,
Map<String, Object> args) {
this.methodName = methodName;
this.siteId = siteId;
this.args = args;
}
/*
* (non-Javadoc)
*
* @see
* com.raytheon.uf.common.python.concurrent.IPythonExecutor#execute(com.
* raytheon.uf.common.python.PythonInterpreter)
*/
@Override
public String execute(IscScript script) {
String retVal = null;
try {
script.execute(methodName, args, siteId);
} catch (JepException e) {
String msg = "Python error executing GFE ISC script ["
+ script.getScriptName() + "]: " + e.getLocalizedMessage();
statusHandler.handle(Priority.ERROR, msg, e);
retVal = msg;
} catch (Throwable t) {
String msg = "Unexpected Java Exception executing GFE ISC script ["
+ script.getScriptName() + "]: " + t.getLocalizedMessage();
statusHandler.handle(Priority.ERROR, msg, t);
retVal = msg;
}
return retVal;
}
}

View file

@ -0,0 +1,78 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.edex.plugin.gfe.isc;
import jep.JepException;
import com.raytheon.uf.common.python.concurrent.AbstractPythonScriptFactory;
import com.raytheon.uf.common.status.IUFStatusHandler;
import com.raytheon.uf.common.status.UFStatus;
import com.raytheon.uf.common.status.UFStatus.Priority;
/**
* Instantiates a {@link IscScript} on a separate thread.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Mar 11, 2013 dgilling Initial creation
*
* </pre>
*
* @author dgilling
* @version 1.0
*/
public class IscScriptFactory extends AbstractPythonScriptFactory<IscScript> {
private static final IUFStatusHandler statusHandler = UFStatus
.getHandler(IscScriptFactory.class);
private static final String SCRIPT_EXTENSION = ".py";
/**
* @param name
* @param maxThreads
*/
public IscScriptFactory(String name, int maxThreads) {
super(name, maxThreads);
}
/*
* (non-Javadoc)
*
* @see
* com.raytheon.uf.common.python.concurrent.AbstractPythonScriptFactory#
* createPythonScript()
*/
@Override
public IscScript createPythonScript() {
try {
return new IscScript(getName() + SCRIPT_EXTENSION);
} catch (JepException e) {
statusHandler.handle(Priority.ERROR,
"Unable to create GFE ISC script [" + getName() + "]", e);
}
return null;
}
}

View file

@ -1,62 +0,0 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.edex.plugin.gfe.server.handler;
import com.raytheon.edex.plugin.gfe.isc.GfeScriptExecutor;
import com.raytheon.uf.common.dataplugin.gfe.request.CreateNetCDFGridRequest;
import com.raytheon.uf.common.dataplugin.gfe.server.message.ServerResponse;
import com.raytheon.uf.common.serialization.comm.IRequestHandler;
/**
* TODO Add Description
*
* <pre>
*
* SOFTWARE HISTORY
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Sep 24, 2010 dgilling Initial creation
*
* </pre>
*
* @author dgilling
* @version 1.0
*/
public class CreateNetCDFGridRequestHandler implements
IRequestHandler<CreateNetCDFGridRequest> {
@Override
public ServerResponse<String> handleRequest(CreateNetCDFGridRequest request)
throws Exception {
ServerResponse<String> sr = new ServerResponse<String>();
GfeScriptExecutor scriptRunner = new GfeScriptExecutor();
String retVal = scriptRunner.execute("ifpnetCDF "
+ request.getArgString());
if (!retVal.equals(GfeScriptExecutor.SUCCESS)) {
sr.addMessage(retVal);
}
return sr;
}
}

View file

@ -0,0 +1,102 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.edex.plugin.gfe.server.handler;
import java.util.HashMap;
import java.util.Map;
import com.raytheon.edex.plugin.gfe.isc.IscScript;
import com.raytheon.edex.plugin.gfe.isc.IscScriptExecutor;
import com.raytheon.uf.common.dataplugin.gfe.request.ExecuteIfpNetCDFGridRequest;
import com.raytheon.uf.common.dataplugin.gfe.server.message.ServerResponse;
import com.raytheon.uf.common.python.concurrent.PythonJobCoordinator;
import com.raytheon.uf.common.serialization.comm.IRequestHandler;
import com.raytheon.uf.common.status.IUFStatusHandler;
import com.raytheon.uf.common.status.UFStatus;
/**
* {@link IRequestHandler} class for {@link ExecuteIfpNetCDFGridRequest} that
* executes the python script ifpnetCDF to export GFE grids to the NetCDF file
* format.
*
* <pre>
*
* SOFTWARE HISTORY
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Sep 24, 2010 dgilling Initial creation
* Mar 11, 2013 #1759 dgilling Re-write using new IscScript classes.
*
* </pre>
*
* @author dgilling
* @version 1.0
*/
public class ExecuteIfpNetCDFGridRequestHandler implements
IRequestHandler<ExecuteIfpNetCDFGridRequest> {
private static final IUFStatusHandler statusHandler = UFStatus
.getHandler(ExecuteIfpNetCDFGridRequestHandler.class);
private static final String METHOD_NAME = "main";
private final PythonJobCoordinator<IscScript> threadPool;
public ExecuteIfpNetCDFGridRequestHandler(
PythonJobCoordinator<IscScript> threadPool) {
this.threadPool = threadPool;
}
@Override
public ServerResponse<Boolean> handleRequest(ExecuteIfpNetCDFGridRequest request)
throws Exception {
ServerResponse<Boolean> sr = new ServerResponse<Boolean>();
sr.setPayload(Boolean.FALSE);
statusHandler.debug("Received ifpnetCDF request: " + request);
Map<String, Object> args = new HashMap<String, Object>();
args.put("outputFilename", request.getOutputFilename());
args.put("parmList", request.getParmList());
args.put("databaseID", request.getDatabaseID().toString());
args.put("startTime", request.getStartTime());
args.put("endTime", request.getEndTime());
args.put("mask", request.getMask());
args.put("geoInfo", request.isGeoInfo());
args.put("compressFileFlag", request.isCompressFile());
args.put("configFileName", request.getConfigFileName());
args.put("compressFileFactor", request.getCompressFileFactor());
args.put("trim", request.isTrim());
args.put("krunch", request.isKrunch());
args.put("userID", request.getUserID());
args.put("logFileName", request.getLogFileName());
IscScriptExecutor executor = new IscScriptExecutor(METHOD_NAME,
request.getSiteID(), args);
String retVal = threadPool.submitSyncJob(executor);
if (retVal != null) {
sr.addMessage(retVal);
return sr;
}
sr.setPayload(Boolean.TRUE);
return sr;
}
}

View file

@ -1,12 +1,22 @@
package com.raytheon.edex.plugin.gfe.server.handler;
import com.raytheon.edex.plugin.gfe.isc.GfeScriptExecutor;
import java.util.HashMap;
import java.util.Map;
import com.raytheon.edex.plugin.gfe.isc.IscScript;
import com.raytheon.edex.plugin.gfe.isc.IscScriptExecutor;
import com.raytheon.edex.site.SiteUtil;
import com.raytheon.uf.common.dataplugin.gfe.request.ExecuteIscMosaicRequest;
import com.raytheon.uf.common.dataplugin.gfe.server.message.ServerResponse;
import com.raytheon.uf.common.python.concurrent.PythonJobCoordinator;
import com.raytheon.uf.common.serialization.comm.IRequestHandler;
import com.raytheon.uf.common.status.IUFStatusHandler;
import com.raytheon.uf.common.status.UFStatus;
/**
* TODO Add Description
* {@link IRequestHandler} class for {@link ExecuteIscMosaicRequest} that
* executes the python script iscMosaic, which imports GFE grids from a NetCDF
* file.
*
* <pre>
*
@ -14,6 +24,7 @@ import com.raytheon.uf.common.serialization.comm.IRequestHandler;
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Sep 15, 2010 dgilling Initial creation
* Mar 12, 2013 #1759 dgilling Re-write using new IscScript classes.
*
* </pre>
*
@ -22,20 +33,65 @@ import com.raytheon.uf.common.serialization.comm.IRequestHandler;
*/
public class ExecuteIscMosaicRequestHandler implements
IRequestHandler<ExecuteIscMosaicRequest> {
private static final IUFStatusHandler statusHandler = UFStatus
.getHandler(ExecuteIscMosaicRequest.class);
private static final String METHOD_NAME = "main";
private final PythonJobCoordinator<IscScript> threadPool;
public ExecuteIscMosaicRequestHandler(
PythonJobCoordinator<IscScript> threadPool) {
this.threadPool = threadPool;
}
@Override
public ServerResponse<String> handleRequest(ExecuteIscMosaicRequest request)
public ServerResponse<Boolean> handleRequest(ExecuteIscMosaicRequest request)
throws Exception {
ServerResponse<String> sr = new ServerResponse<String>();
GfeScriptExecutor scriptRunner = new GfeScriptExecutor();
ServerResponse<Boolean> sr = new ServerResponse<Boolean>();
sr.setPayload(Boolean.FALSE);
String retVal = scriptRunner.execute("iscMosaic "
+ request.getArgString());
statusHandler.debug("Received iscMosaic request: " + request);
Map<String, Object> args = new HashMap<String, Object>();
args.put("siteID", determineSiteId(request.getSiteID()));
args.put("userID", request.getUserID());
args.put("databaseID", request.getDatabaseID().toString());
args.put("parmsToProcess", request.getParmsToProcess());
args.put("blankOtherPeriods", request.isBlankOtherPeriods());
args.put("startTime", request.getStartTime());
args.put("endTime", request.getEndTime());
args.put("altMask", request.getAltMask());
args.put("replaceOnly", request.isReplaceOnly());
args.put("eraseFirst", request.isEraseFirst());
args.put("announce", request.getAnnounce());
args.put("renameWE", request.isRenameWE());
args.put("iscSends", request.isIscSends());
args.put("inFiles", request.getInFiles());
args.put("ignoreMask", request.isIgnoreMask());
args.put("adjustTranslate", request.isAdjustTranslate());
args.put("deleteInput", request.isDeleteInput());
args.put("parmsToIgnore", request.getParmsToIgnore());
args.put("gridDelay", request.getGridDelay());
args.put("logFileName", request.getLogFileName());
if (!retVal.equals(GfeScriptExecutor.SUCCESS)) {
IscScriptExecutor executor = new IscScriptExecutor(METHOD_NAME,
request.getSiteID(), args);
String retVal = threadPool.submitSyncJob(executor);
if (retVal != null) {
sr.addMessage(retVal);
return sr;
}
sr.setPayload(Boolean.TRUE);
return sr;
}
private String determineSiteId(String inputSite) {
if ((inputSite == null) || inputSite.isEmpty()) {
return SiteUtil.getSite();
} else {
return inputSite;
}
}
}

View file

@ -20,7 +20,7 @@
import cPickle
import LogStream, siteConfig, tempfile, os, sys, JUtil, subprocess, traceback
import LogStream, tempfile, os, sys, JUtil, subprocess, traceback
import time, copy, string, iscUtil
from com.raytheon.edex.plugin.gfe.isc import IRTManager
@ -39,6 +39,9 @@ from com.raytheon.edex.plugin.gfe.isc import IRTManager
# 01/25/13 1447 dgilling Implement routines needed by
# iscDataRec for VTEC table
# sharing.
# 03/13/13 1759 dgilling Move siteConfig imports into
# functions where module is used
# to interact better with IscScript.
#
#
#
@ -64,7 +67,9 @@ def logDebug(*msg):
# called by iscDataRec when another site has requested the active table
# returns the active table, filtered, pickled.
def getVTECActiveTable(siteAndFilterInfo, xmlPacket):
import siteConfig
import VTECPartners
if not VTECPartners.VTEC_RESPOND_TO_TABLE_REQUESTS:
return #respond is disabled
@ -154,6 +159,8 @@ def getVTECActiveTable(siteAndFilterInfo, xmlPacket):
#when we receive a requested active table from another site, this function
#is called from iscDataRec
def putVTECActiveTable(strTable, xmlPacket):
import siteConfig
#write the xmlpacket to a temporary file, if one was passed
inDir = os.path.join(siteConfig.GFESUITE_PRDDIR, "ATBL")
if xmlPacket is not None:
@ -351,6 +358,7 @@ def serviceISCRequest(xmlRequest):
# We take this information, convert it into a different format,
# and queue the request via the IFPServer to the SendISCMgr
import IrtAccess
import siteConfig
import xml
from xml.etree import ElementTree
from xml.etree.ElementTree import Element, SubElement

View file

@ -60,6 +60,7 @@ from com.raytheon.uf.common.localization import LocalizationContext_Localization
# Date Ticket# Engineer Description
# ------------ ---------- ----------- --------------------------
# 07/06/09 1995 bphillip Initial Creation.
# 03/11/13 1759 dgilling Removed unneeded methods.
#
#
#
@ -67,52 +68,6 @@ from com.raytheon.uf.common.localization import LocalizationContext_Localization
BATCH_WRITE_COUNT = 10
BATCH_DELAY = 0.0
###-------------------------------------------------------------------------###
### Prints the usage message
def usage():
print """
-h hostname: Host name upon which the ifpServer is running.
-r RPC port: RPC port upon which the ifpServer is running.
-u userID: The user ID to connect with
-o output file: Specifies the name of the output file.
-d database id: DatabaseID from which to get the data.
format: (DEN_GRID__eta_19980604_1200)
-p parmName: Optional. If none specified, get all parms for
the database listed. There may be several
parm names specified.
-s start time: Optional. If no start time specified,
make start time = 0.
format: YYYYMMDD_HHMM (e.g. 19980604_1200)
-e end time: Optional. If no end time specified, make end
time = Abstime::MaxFutureTime().
format: (19980604_1200)
-m mask Optional. Specifies the edit area to be used
as the clip mask. If no mask was specified
then the entire domain will be used. All
values outside the mask will be assigned
a missing value.
-t [no argument] Optional. If present, trim data resolution.
-g [no argument] Optional. If present, topography, latitude
and longitude grids will be stored.
-c [no argument] Optional. If present, the netCDF file will be
compressed by the gzip.
-f factor Optional. When provided in conjunction with the -c switch,
provides the compression factor of gzip (1-9). Default
is 6.
-k [no argument] Optional. If present, the netCDF file is really
shrunk, by using bytes and shorts to represent floats.
Requires the -t switch.
-C configIntervalFilename
Optional. If present, controls the interval/spacing of
the grids. Identifies a configuration file defining
the timing constraints. The filename identifies a
file within the ifpServer TEXT/Utility directory and
must be a Python file.
"""
ifpNetcdfLogger=None
## Logging methods ##
@ -135,135 +90,7 @@ def logVerbose(*msg):
def logDebug(*msg):
logVerbose(iscUtil.tupleToString(*msg))
###-------------------------------------------------------------------------###
### Parses the command line options and saves the data in argDict
def getArgs(argv):
try:
optlist, args = getopt.getopt(argv[1:],
'v:h:r:o:p:d:s:e:u:m:gctkf:C:')
# optlist, args = getopt.getopt(sys.argv[1:],
# 'h:r:o:p:d:s:e:u:m:gctkf:C:')
except getopt.error, val:
print val
usage()
return
# initialize input arguments
host = ""
port = -1
outputFilename = ""
parmList = []
databaseID = ""
startTime = ""
endTime = ""
mask = ""
geoInfo = 0
compressFile = 0
trim = 0
userID = "SITE"
krunch = 0
compressFileFactor = 6
configFileName = None
logFile=None
try:
import siteConfig
host = siteConfig.GFESUITE_SERVER
port = int(siteConfig.GFESUITE_PORT)
except:
pass
for opt in optlist:
if opt[0] == '-h':
host = opt[1]
elif opt[0] == '-r':
port = int(opt[1])
elif opt[0] == '-o':
outputFilename = opt[1]
elif opt[0] == '-C':
configFileName = opt[1]
elif opt[0] == '-p':
p = opt[1]
# Add SFC if necessary
if string.find(p, "_SFC") == -1:
p = p + "_SFC"
if p not in parmList:
parmList.append(p)
elif opt[0] == '-d':
databaseID = opt[1]
elif opt[0] == '-u':
userID = opt[1]
elif opt[0] == '-s':
startTime = opt[1]
elif opt[0] == '-f':
compressFileFactor = int(opt[1])
elif opt[0] == '-e':
endTime = opt[1]
elif opt[0] == '-m':
mask = opt[1]
elif opt[0] == '-g':
geoInfo = 1
elif opt[0] == '-t':
trim = 1
elif opt[0] == '-k':
krunch = 1
elif opt[0] == '-c':
compressFile = 1
elif opt[0] == '-v':
logFile=opt[1]
# Create dictionary of arguments
argDict = {
"host" : host,
"port" : port,
"outputFilename": outputFilename,
"parmList": parmList,
"databaseID": databaseID,
"startTime": startTime,
"endTime": endTime,
"mask": mask,
"geoInfo": geoInfo,
"compressFile" : compressFile,
"configFileName" : configFileName,
"compressFileFactor" : compressFileFactor,
"trim" : trim,
"krunch" : krunch,
"userID" : userID,
"logFile" : logFile,
}
return argDict
###-------------------------------------------------------------------------###
### Checks each argument and takes action where appropriate
def checkArgs(argDict):
if argDict['host'] == '':
usage()
logProblem("You must specify an ifpServer host name.")
raise Exception, "You must specify an ifpServer host name."
if argDict['port'] == -1:
usage()
logProblem("You must specify an ifpServer port number.")
raise Exception, "You must specify an ifpServer port number."
if argDict['databaseID'] == '':
usage()
logProblem("You must specify a database id.")
raise Exception, "You must specify a database id."
if argDict['outputFilename'] == '':
argDict['outputFilename'] = 'ifpnetCDFFile.cdf'
# validate start/end times
if argDict['startTime'] == '':
argDict['startTime'] = '19700101_0000'
if argDict['endTime'] == '':
argDict['endTime'] = '20371231_2359'
# must have trim, if krunch specified
if argDict['krunch'] == 1 and argDict['trim'] == 0:
argDict['krunch'] = 0
return argDict
class WECache(object):
def __init__(self, we, inv):
@ -1474,24 +1301,39 @@ def determineSamplingValues(samplingDef, parmName, inventory, currentTime):
return inven
def executeIfpNetCDF(host, port, outputFilename, parmList, databaseID, startTime, endTime, mask, geoInfo, compressFileFlag, configFileName, compressFileFactor, trim, krunch, userID):
if ifpNetcdfLogger is None:
initLogger()
if type(parmList) != list:
parmList = JUtil.javaStringListToPylist(parmList)
argDict = {"host":host, "port":port, "outputFilename":outputFilename, "parmList":parmList,
"databaseID":databaseID, "startTime":startTime, "endTime":endTime, "mask":mask,
"geoInfo":geoInfo, "compressFile":compressFileFlag, "configFileName":configFileName,
"compressFileFactor":compressFileFactor, "trim":trim, "krunch":krunch, "userID":userID}
argDict = checkArgs(argDict)
###-------------------------------------------------------------------------###
### Main program
def main(outputFilename, parmList, databaseID, startTime,
endTime, mask, geoInfo, compressFileFlag, configFileName,
compressFileFactor, trim, krunch, userID, logFileName):
initLogger(logFileName)
# LogStream.ttyLogOn()
logEvent("ifpnetCDF Starting")
# LogStream.logEvent(AFPS.DBSubsystem_getBuildDate(),
# AFPS.DBSubsystem_getBuiltBy(), AFPS.DBSubsystem_getBuiltOn(),
# AFPS.DBSubsystem_getBuildVersion())
try:
len(parmList)
except TypeError:
parmList = JUtil.javaObjToPyVal(parmList)
argDict = {"outputFilename": outputFilename,
"parmList": parmList,
"databaseID": databaseID,
"startTime": startTime,
"endTime": endTime,
"mask": mask,
"geoInfo": bool(geoInfo),
"compressFile": bool(compressFileFlag),
"configFileName": configFileName,
"compressFileFactor": int(compressFileFactor),
"trim": bool(trim),
"krunch": bool(krunch),
"userID": userID}
logEvent("Command: ", argDict)
a = os.times()
cpu0 = a[0] + a[1]
start = a[4]
@ -1500,7 +1342,7 @@ def executeIfpNetCDF(host, port, outputFilename, parmList, databaseID, startTime
try:
timeRange = makeTimeRange(argDict['startTime'], argDict['endTime'])
except:
return
sys.exit(1)
# See if the databaseID is valid. An exception will be tossed
db = IFPDB(argDict['databaseID'])
@ -1617,34 +1459,12 @@ def executeIfpNetCDF(host, port, outputFilename, parmList, databaseID, startTime
"%-.2f" % (stop - stop1), "/", "%-.2f" % (cpugz - cpu), "compress,",
"%-.2f" % (stop - start), "/", "%-.2f" % (cpugz - cpu0), "total")
#logEvent("stats: ", client.getStats())
###-------------------------------------------------------------------------###
### Main program
def main(argv):
#LogStream.logEvent(AFPS.DBSubsystem_getBuildDate(),
# AFPS.DBSubsystem_getBuiltBy(), AFPS.DBSubsystem_getBuiltOn(),
# AFPS.DBSubsystem_getBuildVersion())
if type(argv) is not list:
argv = JUtil.javaStringListToPylist(argv)
argDict = getArgs(argv)
initLogger(argDict["logFile"])
logEvent("ifpnetCDF Starting")
logEvent("Command: ",iscUtil.tupleToString(*argv))
executeIfpNetCDF(argDict["host"], argDict["port"], argDict["outputFilename"], argDict["parmList"], argDict["databaseID"],
argDict["startTime"], argDict["endTime"], argDict["mask"], argDict["geoInfo"], argDict["compressFile"],
argDict["configFileName"], argDict["compressFileFactor"], argDict["trim"], argDict["krunch"], argDict["userID"])
logEvent("ifpnetCDF Finished")
if __name__ == "__main__":
pass
#main()
#if __name__ == "__main__":
# main()
# profile stuff
# import profile, pstats
# profile.run('main()', 'pyprof.out')
@ -1652,4 +1472,3 @@ if __name__ == "__main__":
# p.strip_dirs()
# p.sort_stats('time', 'calls').print_stats(15)
# p.print_callers(15)

View file

@ -3,20 +3,20 @@
##
# This software was developed and / or modified by Raytheon Company,
# pursuant to Contract DG133W-05-CQ-1067 with the US Government.
#
# U.S. EXPORT CONTROLLED TECHNICAL DATA
# pursuant to Contract DG133W-05-CQ-1067 with the US Government.
#
# U.S. EXPORT CONTROLLED TECHNICAL DATA
# This software product contains export-restricted data whose
# export/transfer/disclosure is restricted by U.S. law. Dissemination
# to non-U.S. persons whether in the United States or abroad requires
# an export license or other authorization.
#
# Contractor Name: Raytheon Company
# Contractor Address: 6825 Pine Street, Suite 340
# Mail Stop B8
# Omaha, NE 68106
# 402.291.0100
#
# Contractor Name: Raytheon Company
# Contractor Address: 6825 Pine Street, Suite 340
# Mail Stop B8
# Omaha, NE 68106
# 402.291.0100
#
# See the AWIPS II Master Rights File ("Master Rights File.pdf") for
# further licensing information.
##
@ -41,7 +41,7 @@ exec $GFESUITE_HOME/bin/run/iscDataRec1 -S -O $0 ${1+"$@"}
import iscMosaic,iscUtil
import os, stat, sys, re, string, traceback, types
import time, xml, LogStream, siteConfig, IrtAccess
import time, xml, LogStream, IrtAccess
import IrtServer
from xml.etree import ElementTree
from xml.etree.ElementTree import Element, SubElement
@ -57,6 +57,9 @@ from java.util import ArrayList
# ------------ ---------- ----------- --------------------------
# 07/06/09 1995 bphillip Initial Creation.
# 01/29/13 1447 dgilling Implement VTEC table sharing.
# 03/12/13 1759 dgilling Bypass command-line processing
# for iscMosaic, support changes
# to IscReceiveSrv.
#
#
#
@ -94,7 +97,8 @@ def purgeFiles(msgid, files):
def execIscDataRec(MSGID,SUBJECT,FILES):
import siteConfig
try:
# logEvent('*** iscDataRec ***', sys.argv[1:])
logEvent('SUBJECT:', SUBJECT, 'MSGID:', MSGID,"FILES:",FILES)
@ -208,29 +212,26 @@ def execIscDataRec(MSGID,SUBJECT,FILES):
elif SUBJECT == 'GET_ACTIVE_TABLE2':
IrtServer.getVTECActiveTable(fpData, xmlFileBuf)
elif SUBJECT in ['ISCGRIDS', 'ISCGRIDS2']:
files = ArrayList()
files.add(dataFile)
args = []
args.append(" ")
args.append("-h")
args.append(siteConfig.GFESUITE_SERVER)
args.append("-r")
args.append(siteConfig.GFESUITE_PORT)
args.append("-d")
args.append(siteConfig.GFESUITE_SITEID+"_GRID__ISC_00000000_0000")
args.append("-T")
args.append("-b")
for i in range(0,files.size()):
args.append("-f")
args.append(files.get(i))
args.append("-w")
args.append("ISC: ")
args.append("-k")
args.append("-o")
args = {"siteID": siteConfig.GFESUITE_SITEID,
"userID": 'SITE',
"databaseID": siteConfig.GFESUITE_SITEID+"_GRID__ISC_00000000_0000",
"parmsToProcess": [],
"blankOtherPeriods": True,
"startTime": None,
"endTime": None,
"altMask": None,
"replaceOnly": False,
"eraseFirst": False,
"announce": "ISC: ",
"renameWE": True,
"iscSends": False,
"inFiles": [dataFile],
"ignoreMask": False,
"adjustTranslate": True,
"deleteInput": True,
"parmsToIgnore": [],
"gridDelay": 0.0,
"logFileName": None}
mosaic = iscMosaic.IscMosaic(args)
mosaic.execute()
@ -276,14 +277,14 @@ def execIscDataRec(MSGID,SUBJECT,FILES):
def main(argv):
initLogger()
try:
if type(argv) != 'list':
if type(argv) is not list:
import JUtil
argv = JUtil.javaStringListToPylist(argv)
logEvent('*** iscDataRec ***', argv[1:])
argv = JUtil.javaObjToPyVal(argv)
logEvent('*** iscDataRec ***', argv)
try:
MSGID = argv[1]
SUBJECT = argv[2]
FILES = argv[3].split(',')
MSGID = argv[0]
SUBJECT = argv[1]
FILES = argv[2].split(',')
logEvent('SUBJECT:', SUBJECT, 'MSGID:', MSGID)
#log the incoming files and size

View file

@ -52,6 +52,7 @@ from com.vividsolutions.jts.geom import Coordinate
# Date Ticket# Engineer Description
# ------------ ---------- ----------- --------------------------
# 07/06/09 1995 bphillip Initial Creation.
# 03/12/13 1759 dgilling Change how ifpnetCDF is called.
#
#
#
@ -425,38 +426,22 @@ def executeIscExtract(parmNames, databaseName, startTime, endTime,
else: #no clipping, or different projection
maskName = "ISC_Send_Area"
# Run ifpnetCDF for the data
argv = []
argv.append("ifpnetCDF")
argv.append("-h")
argv.append(siteConfig.GFESUITE_SERVER)
argv.append("-r")
argv.append(siteConfig.GFESUITE_PORT)
argv.append("-o")
argv.append(fname)
argv.append("-C")
argv.append("iscSendSampleDef")
for p in dest['parms']:
argv.append("-p")
argv.append(p)
argv.append("-d")
argv.append(dbid)
argv.append("-s")
argv.append(startTR)
argv.append("-e")
argv.append(endTR)
argv.append("-m")
argv.append(maskName)
argv.append("-c")
argv.append("-f")
argv.append("6")
argv.append("-t")
argv.append("-k")
argv.append("-u")
argv.append("iscExtract")
ifpnetCDF.main(argv)
# Run ifpnetCDF for the data
argv = {"outputFilename": fname,
"parmList": dest['parms'],
"databaseID": dbid,
"startTime": startTR,
"endTime": endTR,
"mask": maskName,
"geoInfo": False,
"compressFileFlag": True,
"configFileName": "iscSendSampleDef",
"compressFileFactor": 6,
"trim": True,
"krunch": True,
"userID": "iscExtract",
"logFileName": None}
ifpnetCDF.main(**argv)
fname = fname + '.gz'
size = os.stat(fname)[stat.ST_SIZE]

View file

@ -72,7 +72,9 @@ from com.raytheon.uf.edex.database.cluster import ClusterTask
# Date Ticket# Engineer Description
# ------------ ---------- ----------- --------------------------
# 07/06/09 1995 bphillip Initial Creation.
# 01/17/13 15588 jdynina Fixed Publish history removal
# 01/17/13 15588 jdynina Fixed Publish history removal
# 03/12/13 1759 dgilling Remove unnecessary command line
# processing.
#
#
@ -192,32 +194,37 @@ class IscMosaic:
self.__logger=iscUtil.getLogger("iscMosaic",self.__logFile)
def __init__(self, args):
import siteConfig
self.__host = 0
self.__port = 0
self.__userID = 'SITE'
self.__mysite = args['siteID']
self.__userID = args['userID']
self.__db = None # ifpServer database object
self.__dbGrid = None
self.__parmsToProcess = []
self.__blankOtherPeriods = 0
self.__processTimePeriod = None
self.__altMask = None
self.__replaceOnly = 0
self.__eraseFirst = 0
self.__announce = ""
self.__renameWE = 0
self.__iscSends = 0
self.__databaseID = ''
self.__inFiles = []
self.__ignoreMask = 0
self.__adjustTranslate = 0
self.__deleteInput = 0
self.__parmsToIgnore = []
self.__gridDelay = 0.0
self.__logFile = None
self.__parmsToProcess = args['parmsToProcess']
self.__blankOtherPeriods = args['blankOtherPeriods']
self.__altMask = args['altMask']
self.__replaceOnly = args['replaceOnly']
self.__eraseFirst = args['eraseFirst']
self.__announce = args['announce']
self.__renameWE = args['renameWE']
self.__iscSends = args['iscSends']
if args['databaseID'] is not None:
self.__databaseID = args['databaseID']
else:
self.__databaseID = self.__mysite + "_GRID__ISC_00000000_0000"
self.__inFiles = args['inFiles']
self.__ignoreMask = args['ignoreMask']
self.__adjustTranslate = args['adjustTranslate']
self.__deleteInput = args['deleteInput']
self.__parmsToIgnore = args['parmsToIgnore']
self.__gridDelay = args['gridDelay']
self.__logFile = args['logFileName']
self.__getArgs(args)
startTime = 0
if args['startTime'] is not None:
startTime = self.__decodeTimeString(args['startTime'])
endTime = int(2 ** 30 - 1 + 2 ** 30)
if args['endTime'] is not None:
endTime = self.__decodeTimeString(args['endTime'])
self.__processTimePeriod = (startTime, endTime)
self.__initLogger()
@ -236,97 +243,6 @@ class IscMosaic:
def logDebug(self,*msg):
self.logVerbose(iscUtil.tupleToString(*msg))
#------------------------------------------------------------------------
# Read command line arguments
#------------------------------------------------------------------------
def __getArgs(self, args):
try:
optlist, args = getopt.getopt(args[1:],
'v:h:r:d:p:u:f:bs:e:xzkna:w:i:D:oST')
except getopt.error, val:
print val
return
startTime = 0
endTime = int(2 ** 30 - 1 + 2 ** 30)
import siteConfig
try:
self.__host = siteConfig.GFESUITE_SERVER
self.__port = int(siteConfig.GFESUITE_PORT)
self.__mysite = siteConfig.GFESUITE_SITEID
self.__databaseID = self.__mysite + "_GRID__ISC_00000000_0000"
except:
pass
for opt in optlist:
if opt[0] == '-h':
self.__host = opt[1]
if opt[0] == '-a':
self.__altMask = opt[1]
elif opt[0] == '-r':
self.__port = int(opt[1])
elif opt[0] == '-b':
self.__blankOtherPeriods = 1
elif opt[0] == '-u':
self.__userID = opt[1]
elif opt[0] == '-T':
self.__adjustTranslate = 1
elif opt[0] == '-k':
self.__deleteInput = 1
elif opt[0] == '-d':
self.__databaseID = opt[1]
elif opt[0] == '-D':
self.__gridDelay = float(opt[1])
elif opt[0] == '-p':
p = opt[1]
# add SFC if necessary
if string.find(p, "_SFC") == -1:
p = p + "_SFC"
if p not in self.__parmsToProcess:
self.__parmsToProcess.append(p)
elif opt[0] == '-i':
i = opt[1]
# add SFC if necessary
if string.find(i, "_SFC") == -1:
i = i + "_SFC"
if i not in self.__parmsToIgnore:
self.__parmsToIgnore.append(i)
elif opt[0] == '-f':
self.__inFiles.append(opt[1])
elif opt[0] == '-s':
startTime = self.__decodeTimeString(opt[1])
elif opt[0] == '-e':
endTime = self.__decodeTimeString(opt[1])
elif opt[0] == '-z':
self.__eraseFirst = 1
elif opt[0] == '-x':
self.__replaceOnly = 1
elif opt[0] == '-w':
self.__announce = opt[1]
elif opt[0] == '-o':
self.__renameWE = 1
elif opt[0] == '-n':
self.__ignoreMask = 1
elif opt[0] == '-S':
self.__iscSends = 1
elif opt[0] == '-v':
self.__logFile = opt[1]
if len(self.__inFiles) > 1 and self.__eraseFirst == 1:
self.logProblem(\
"Multiple input files [-f switches] and -z switch not compatible")
raise Exception, "Bad command line"
if self.__ignoreMask == 1 and self.__altMask is not None:
self.logProblem(\
"-n and -a altMask switches not compatible")
raise Exception, "Bad command line"
self.__inFiles = JUtil.pyValToJavaObj(self.__inFiles)
self.__processTimePeriod = (startTime, endTime)
def execute(self):
self.logEvent("iscMosaic Starting")
@ -348,12 +264,12 @@ class IscMosaic:
self.__myOfficeType = IFPServerConfigManager.getServerConfig(DatabaseID(self.__databaseID).getSiteId()).officeType()
#process each input file
for i in range(0, self.__inFiles.size()):
for file in self.__inFiles:
self.__areaMask = None
self.__processInputFile(str(self.__inFiles.get(i)))
self.__processInputFile(file)
if self.__deleteInput:
os.remove(str(self.__inFiles.get(i)))
os.remove(file)
self.logEvent("iscMosaic Finished")
@ -1540,9 +1456,43 @@ class IscMosaic:
self.__dbGrid = None
def main(argv):
if type(argv) != 'list':
argv = JUtil.javaStringListToPylist(argv)
def convertList(unknownList):
retVal = unknownList
try:
len(unknownList)
except TypeError:
retVal = JUtil.javaObjToPyVal(unknownList)
return retVal
def main(siteID, userID, databaseID, parmsToProcess, blankOtherPeriods,
startTime, endTime, altMask, replaceOnly, eraseFirst,
announce, renameWE, iscSends, inFiles, ignoreMask,
adjustTranslate, deleteInput, parmsToIgnore, gridDelay, logFileName):
# convert Java types to python and send to IscMosaic for execution
parmsToProcess = convertList(parmsToProcess)
inFiles = convertList(inFiles)
parmsToIgnore = convertList(parmsToIgnore)
argv = {"siteID": siteID,
"userID": userID,
"databaseID": databaseID,
"parmsToProcess": parmsToProcess,
"blankOtherPeriods": bool(blankOtherPeriods),
"startTime": startTime,
"endTime": endTime,
"altMask": altMask,
"replaceOnly": bool(replaceOnly),
"eraseFirst": bool(eraseFirst),
"announce": announce,
"renameWE": bool(renameWE),
"iscSends": bool(iscSends),
"inFiles": inFiles,
"ignoreMask": bool(ignoreMask),
"adjustTranslate": bool(adjustTranslate),
"deleteInput": bool(deleteInput),
"parmsToIgnore": parmsToIgnore,
"gridDelay": float(gridDelay),
"logFileName": logFileName}
mosaic = IscMosaic(argv)
mosaic.execute()
mosaic = None

View file

@ -23,7 +23,6 @@ import xml, pickle, tempfile, os
from xml.etree import ElementTree
from xml.etree.ElementTree import Element, SubElement
import LogStream
import siteConfig
from datetime import datetime
from time import gmtime,strftime
from java.io import File
@ -48,6 +47,8 @@ from com.raytheon.uf.common.localization import LocalizationContext_Localization
# Date Ticket# Engineer Description
# ------------ ---------- ----------- --------------------------
# 07/06/09 1995 bphillip Initial Creation.
# 03/11/13 1759 dgilling Move siteConfig import into
# methods where it's needed.
#
#
#
@ -279,6 +280,12 @@ def getRequestXML(xml,selectedServers, selectedWEList):
def getLogger(scriptName, logName=None):
import logging
# be relocating this import here we allow
# com.raytheon.edex.plugin.gfe.isc.IscScript to dynamically
# modify its include path with the proper siteConfig just before
# execution time
import siteConfig
if logName is None:
logPath=siteConfig.GFESUITE_LOGDIR+"/"+strftime("%Y%m%d", gmtime())
logName=scriptName+".log"

View file

@ -37,6 +37,7 @@ import com.raytheon.uf.common.util.FileUtil;
* Oct 9, 2008 njensen Initial creation
* Sep 18, 2012 #1091 randerso added base directory to getGfeConfigIncludePath
* Feb 27, 2013 #1447 dgilling Re-factor based on PythonPathIncludeUtil.
* Mar 11, 2013 #1759 dgilling Add method getGfeConfigLF().
* </pre>
*
* @author njensen
@ -371,6 +372,10 @@ public class GfePyIncludeUtil extends PythonIncludePathUtil {
return PyUtil.buildJepIncludePath(siteConfigDir, baseConfigDir);
}
public static LocalizationFile getGfeConfigLF(LocalizationContext ctx) {
return PATH_MANAGER.getLocalizationFile(ctx, GFE_CONFIG);
}
public static String getVCModulesIncludePath() {
return getPath(PATH_MANAGER.getContext(LocalizationType.COMMON_STATIC,
LocalizationLevel.BASE), VCMODULES);

View file

@ -1,61 +0,0 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.uf.common.dataplugin.gfe.request;
import com.raytheon.uf.common.serialization.annotations.DynamicSerialize;
import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement;
/**
* TODO Add Description
*
* <pre>
*
* SOFTWARE HISTORY
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Sep 24, 2010 dgilling Initial creation
*
* </pre>
*
* @author dgilling
* @version 1.0
*/
@DynamicSerialize
public class CreateNetCDFGridRequest extends AbstractGfeRequest {
@DynamicSerializeElement
private String argString;
/**
* @return the argString
*/
public String getArgString() {
return argString;
}
/**
* @param argString
* the argString to set
*/
public void setArgString(String argString) {
this.argString = argString;
}
}

View file

@ -0,0 +1,237 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.uf.common.dataplugin.gfe.request;
import java.util.List;
import com.raytheon.uf.common.dataplugin.gfe.db.objects.DatabaseID;
import com.raytheon.uf.common.serialization.annotations.DynamicSerialize;
import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement;
/**
* Request object to run ifpnetCDF.
*
* <pre>
*
* SOFTWARE HISTORY
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Sep 24, 2010 dgilling Initial creation
* Mar 11, 2013 #1759 dgilling Re-factoring to use fields instead
* of an argument string.
*
* </pre>
*
* @author dgilling
* @version 1.0
*/
@DynamicSerialize
public class ExecuteIfpNetCDFGridRequest extends AbstractGfeRequest {
@DynamicSerializeElement
private String outputFilename;
@DynamicSerializeElement
private List<String> parmList;
@DynamicSerializeElement
private DatabaseID databaseID;
@DynamicSerializeElement
private String startTime;
@DynamicSerializeElement
private String endTime;
@DynamicSerializeElement
private String mask;
@DynamicSerializeElement
private boolean geoInfo;
@DynamicSerializeElement
private boolean compressFile;
@DynamicSerializeElement
private String configFileName;
@DynamicSerializeElement
private int compressFileFactor;
@DynamicSerializeElement
private boolean trim;
@DynamicSerializeElement
private boolean krunch;
@DynamicSerializeElement
private String userID;
@DynamicSerializeElement
private String logFileName;
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("ExecuteIfpNetCDFGridRequest [outputFilename=");
builder.append(outputFilename);
builder.append(", parmList=");
builder.append(parmList);
builder.append(", databaseID=");
builder.append(databaseID);
builder.append(", startTime=");
builder.append(startTime);
builder.append(", endTime=");
builder.append(endTime);
builder.append(", mask=");
builder.append(mask);
builder.append(", geoInfo=");
builder.append(geoInfo);
builder.append(", compressFile=");
builder.append(compressFile);
builder.append(", configFileName=");
builder.append(configFileName);
builder.append(", compressFileFactor=");
builder.append(compressFileFactor);
builder.append(", trim=");
builder.append(trim);
builder.append(", krunch=");
builder.append(krunch);
builder.append(", userID=");
builder.append(userID);
builder.append(", logFileName=");
builder.append(logFileName);
builder.append("]");
return builder.toString();
}
public String getOutputFilename() {
return outputFilename;
}
public void setOutputFilename(String outputFilename) {
this.outputFilename = outputFilename;
}
public List<String> getParmList() {
return parmList;
}
public void setParmList(List<String> parmList) {
this.parmList = parmList;
}
public DatabaseID getDatabaseID() {
return databaseID;
}
public void setDatabaseID(DatabaseID databaseID) {
this.databaseID = databaseID;
}
public String getStartTime() {
return startTime;
}
public void setStartTime(String startTime) {
this.startTime = startTime;
}
public String getEndTime() {
return endTime;
}
public void setEndTime(String endTime) {
this.endTime = endTime;
}
public String getMask() {
return mask;
}
public void setMask(String mask) {
this.mask = mask;
}
public boolean isGeoInfo() {
return geoInfo;
}
public void setGeoInfo(boolean geoInfo) {
this.geoInfo = geoInfo;
}
public boolean isCompressFile() {
return compressFile;
}
public void setCompressFile(boolean compressFile) {
this.compressFile = compressFile;
}
public String getConfigFileName() {
return configFileName;
}
public void setConfigFileName(String configFileName) {
this.configFileName = configFileName;
}
public int getCompressFileFactor() {
return compressFileFactor;
}
public void setCompressFileFactor(int compressFileFactor) {
this.compressFileFactor = compressFileFactor;
}
public boolean isTrim() {
return trim;
}
public void setTrim(boolean trim) {
this.trim = trim;
}
public boolean isKrunch() {
return krunch;
}
public void setKrunch(boolean krunch) {
this.krunch = krunch;
}
public String getUserID() {
return userID;
}
public void setUserID(String userID) {
this.userID = userID;
}
public String getLogFileName() {
return logFileName;
}
public void setLogFileName(String logFileName) {
this.logFileName = logFileName;
}
}

View file

@ -19,11 +19,14 @@
**/
package com.raytheon.uf.common.dataplugin.gfe.request;
import java.util.List;
import com.raytheon.uf.common.dataplugin.gfe.db.objects.DatabaseID;
import com.raytheon.uf.common.serialization.annotations.DynamicSerialize;
import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement;
/**
* TODO Add Description
* Request object to run iscMosaic.
*
* <pre>
*
@ -31,6 +34,8 @@ import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement;
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Sep 20, 2010 dgilling Initial creation
* Mar 12, 2013 #1759 dgilling Re-factoring to use fields instead
* of an argument string.
*
* </pre>
*
@ -42,21 +47,261 @@ import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement;
public class ExecuteIscMosaicRequest extends AbstractGfeRequest {
@DynamicSerializeElement
private String argString;
private String userID;
/**
* @return the argString
*/
public String getArgString() {
return argString;
@DynamicSerializeElement
private DatabaseID databaseID;
@DynamicSerializeElement
private List<String> parmsToProcess;
@DynamicSerializeElement
private boolean blankOtherPeriods;
@DynamicSerializeElement
private String startTime;
@DynamicSerializeElement
private String endTime;
@DynamicSerializeElement
private String altMask;
@DynamicSerializeElement
private boolean replaceOnly;
@DynamicSerializeElement
private boolean eraseFirst;
@DynamicSerializeElement
private String announce;
@DynamicSerializeElement
private boolean renameWE;
@DynamicSerializeElement
private boolean iscSends;
@DynamicSerializeElement
private List<String> inFiles;
@DynamicSerializeElement
private boolean ignoreMask;
@DynamicSerializeElement
private boolean adjustTranslate;
@DynamicSerializeElement
private boolean deleteInput;
@DynamicSerializeElement
private List<String> parmsToIgnore;
@DynamicSerializeElement
private float gridDelay;
@DynamicSerializeElement
private String logFileName;
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("ExecuteIscMosaicRequest [workstationID=");
builder.append(workstationID);
builder.append(", siteID=");
builder.append(siteID);
builder.append(", userID=");
builder.append(userID);
builder.append(", databaseID=");
builder.append(databaseID);
builder.append(", parmsToProcess=");
builder.append(parmsToProcess);
builder.append(", blankOtherPeriods=");
builder.append(blankOtherPeriods);
builder.append(", startTime=");
builder.append(startTime);
builder.append(", endTime=");
builder.append(endTime);
builder.append(", altMask=");
builder.append(altMask);
builder.append(", replaceOnly=");
builder.append(replaceOnly);
builder.append(", eraseFirst=");
builder.append(eraseFirst);
builder.append(", announce=");
builder.append(announce);
builder.append(", renameWE=");
builder.append(renameWE);
builder.append(", iscSends=");
builder.append(iscSends);
builder.append(", inFiles=");
builder.append(inFiles);
builder.append(", ignoreMask=");
builder.append(ignoreMask);
builder.append(", adjustTranslate=");
builder.append(adjustTranslate);
builder.append(", deleteInput=");
builder.append(deleteInput);
builder.append(", parmsToIgnore=");
builder.append(parmsToIgnore);
builder.append(", gridDelay=");
builder.append(gridDelay);
builder.append(", logFileName=");
builder.append(logFileName);
builder.append("]");
return builder.toString();
}
/**
* @param argString
* the argString to set
*/
public void setArgString(String argString) {
this.argString = argString;
public String getUserID() {
return userID;
}
public void setUserID(String userID) {
this.userID = userID;
}
public DatabaseID getDatabaseID() {
return databaseID;
}
public void setDatabaseID(DatabaseID databaseID) {
this.databaseID = databaseID;
}
public List<String> getParmsToProcess() {
return parmsToProcess;
}
public void setParmsToProcess(List<String> parmsToProcess) {
this.parmsToProcess = parmsToProcess;
}
public boolean isBlankOtherPeriods() {
return blankOtherPeriods;
}
public void setBlankOtherPeriods(boolean blankOtherPeriods) {
this.blankOtherPeriods = blankOtherPeriods;
}
public String getStartTime() {
return startTime;
}
public void setStartTime(String startTime) {
this.startTime = startTime;
}
public String getEndTime() {
return endTime;
}
public void setEndTime(String endTime) {
this.endTime = endTime;
}
public String getAltMask() {
return altMask;
}
public void setAltMask(String altMask) {
this.altMask = altMask;
}
public boolean isReplaceOnly() {
return replaceOnly;
}
public void setReplaceOnly(boolean replaceOnly) {
this.replaceOnly = replaceOnly;
}
public boolean isEraseFirst() {
return eraseFirst;
}
public void setEraseFirst(boolean eraseFirst) {
this.eraseFirst = eraseFirst;
}
public String getAnnounce() {
return announce;
}
public void setAnnounce(String announce) {
this.announce = announce;
}
public boolean isRenameWE() {
return renameWE;
}
public void setRenameWE(boolean renameWE) {
this.renameWE = renameWE;
}
public boolean isIscSends() {
return iscSends;
}
public void setIscSends(boolean iscSends) {
this.iscSends = iscSends;
}
public List<String> getInFiles() {
return inFiles;
}
public void setInFiles(List<String> inFiles) {
this.inFiles = inFiles;
}
public boolean isIgnoreMask() {
return ignoreMask;
}
public void setIgnoreMask(boolean ignoreMask) {
this.ignoreMask = ignoreMask;
}
public boolean isAdjustTranslate() {
return adjustTranslate;
}
public void setAdjustTranslate(boolean adjustTranslate) {
this.adjustTranslate = adjustTranslate;
}
public boolean isDeleteInput() {
return deleteInput;
}
public void setDeleteInput(boolean deleteInput) {
this.deleteInput = deleteInput;
}
public List<String> getParmsToIgnore() {
return parmsToIgnore;
}
public void setParmsToIgnore(List<String> parmsToIgnore) {
this.parmsToIgnore = parmsToIgnore;
}
public float getGridDelay() {
return gridDelay;
}
public void setGridDelay(float gridDelay) {
this.gridDelay = gridDelay;
}
public void setLogFileName(String logFileName) {
this.logFileName = logFileName;
}
public String getLogFileName() {
return logFileName;
}
}

View file

@ -18,14 +18,6 @@
# further licensing information.
##
from dynamicserialize.dstypes.com.raytheon.uf.common.dataplugin.gfe.request import CreateNetCDFGridRequest
from dynamicserialize.dstypes.com.raytheon.uf.common.message import WsId
from dynamicserialize import DynamicSerializationManager
import sys
import os
from ufpy import ThriftClient
from ufpy.UsageOptionParser import UsageOptionParser
#
# Provides a command-line utility to export selected grids to netCDF format.
#
@ -35,82 +27,83 @@ from ufpy.UsageOptionParser import UsageOptionParser
# Date Ticket# Engineer Description
# ------------ ---------- ----------- --------------------------
# 09/23/10 dgilling Initial Creation.
# 03/07/13 1759 dgilling Populate siteID field of
# request based on specified
# DatabaseID.
#
#
#
def main():
(options, args) = validateArgs()
for i in range(1,4):
print >> sys.stderr, "Attempt number: ", i
try:
netCdfRequest = createRequest()
netCdfRequest.setArgString(netCdfRequest.getArgString() + " -h " + options.host + " -r " + str(options.port))
thriftClient = ThriftClient.ThriftClient(options.host, options.port, "/services")
serverResponse = thriftClient.sendRequest(netCdfRequest)
except Exception, e:
print >> sys.stderr, "Unhandled exception thrown during ifpnetCDF processing: \n", str(e)
sys.exit(1)
if (serverResponse.isOkay()):
break
else:
print >> sys.stderr, "Errors occurred during ifpnetCDF processing: ", serverResponse.message()
if (i == 3):
print >> sys.stderr, "Final attempt failed - exiting"
sys.exit(1)
import logging
import os
import sys
from dynamicserialize.dstypes.com.raytheon.uf.common.dataplugin.gfe.request import ExecuteIfpNetCDFGridRequest
from dynamicserialize.dstypes.com.raytheon.uf.common.message import WsId
from ufpy import ThriftClient
from ufpy import UsageArgumentParser
from ufpy.UsageArgumentParser import StoreDatabaseIDAction as StoreDatabaseIDAction
from ufpy.UsageArgumentParser import AppendParmNameAndLevelAction as AppendParmNameAndLevelAction
RETRY_ATTEMPTS = 3
logging.basicConfig(format="%(asctime)s %(name)s %(levelname)s: %(message)s",
datefmt="%H:%M:%S",
level=logging.INFO)
log = logging.getLogger('ifpnetCDF')
def validateArgs():
parser = UsageOptionParser(conflict_handler="resolve")
parser.add_option("-h", action="store", type="string", dest="host",
help="Host name upon which the ifpServer is running.",
metavar="hostname")
parser.add_option("-r", action="store", type="int", dest="port",
help="Port upon which the ifpServer is running.",
metavar="port")
parser.add_option("-u", action="store", type="string", dest="userID",
help="The user ID to connect with",
metavar="userID")
parser.add_option("-o", action="store", type="string", dest="outputFile",
help="Specifies the name of the output file.",
metavar="outputFile")
parser.add_option("-d", action="store", type="string", dest="databaseID",
help="id for output database in ifpServer",
metavar="databaseID")
parser.add_option("-p", action="append", type="string", dest="parmList",
help="Optional. If none specified, get all parms for the database listed. There may be several parm names specified.",
metavar="parmName")
parser.add_option("-s", action="store", type="string", dest="startTime",
help="Optional. If no start time specified, make start time = 0. format: YYYYMMDD_HHMM (e.g. 19980604_1200)",
metavar="startTime")
parser.add_option("-e", action="store", type="string", dest="endTime",
help="Optional. If no end time specified, make end time = Abstime::MaxFutureTime(). format: (19980604_1200)",
metavar="endTime")
parser.add_option("-m", action="store", type="string", dest="mask",
help="Optional. Specifies the edit area to be used as the clip mask. If no mask was specified then the entire domain will be used. All values outside the mask will be assigned a missing value.",
metavar="mask")
parser.add_option("-t", action="store_true", dest="trim",
help="Optional. If present, trim data resolution.")
parser.add_option("-g", action="store_true", dest="geoInfo",
help="Optional. If present, topography, latitude and longitude grids will be stored.")
parser.add_option("-c", action="store_true", dest="compressFile",
help="Optional. If present, the netCDF file will be compressed by the gzip.")
parser.add_option("-f", action="store", type="int", dest="compressFileFactor",
help="Optional. When provided in conjunction with the -c switch, provides the compression factor of gzip (1-9). Default is 6.",
metavar="factor")
parser.add_option("-k", action="store_true", dest="krunch",
help="Optional. If present, the netCDF file is really shrunk, by using bytes and shorts to represent floats. Requires the -t switch.")
parser.add_option("-C", action="store", type="string", dest="configFileName",
help="Optional. If present, controls the interval/spacing of the grids. Identifies a configuration file defining the timing constraints. The filename identifies a file within the ifpServer TEXT/Utility directory and must be a Python file.",
metavar="configIntervalFilename")
parser.add_option("-v", action="store_true", dest="logFile",
help="Optional. If present, the output from the script will be logged to the specified file. If not present, logging will default to ifpnetCDF.log located in GFESUITE_LOGDIR")
def get_and_check_args():
parser = UsageArgumentParser.UsageArgumentParser(prog='ifpnetCDF', conflict_handler="resolve")
parser.add_argument("-h", action="store", dest="host",
help="Host name upon which the ifpServer is running.",
metavar="hostname")
parser.add_argument("-r", action="store", type=int, dest="port",
help="Port upon which the ifpServer is running.",
metavar="port")
parser.add_argument("-u", action="store", dest="userID",
help="The user ID to connect with",
default="SITE", metavar="userID")
parser.add_argument("-o", action="store", dest="outputFilename",
help="Specifies the name of the output file.",
default="ifpnetCDFFile.cdf", metavar="outputFile")
parser.add_argument("-d", action=StoreDatabaseIDAction, dest="databaseID",
required= True,
help="id for output database in ifpServer",
metavar="databaseID")
parser.add_argument("-p", action=AppendParmNameAndLevelAction, dest="parmList",
help="Optional. If none specified, get all parms for the database listed. There may be several parm names specified.",
default=[], metavar="parmName")
parser.add_argument("-s", action="store", dest="startTime",
help="Optional. If no start time specified, make start time = 0. format: YYYYMMDD_HHMM (e.g. 19980604_1200)",
default="19700101_0000", metavar="startTime")
parser.add_argument("-e", action="store", dest="endTime",
help="Optional. If no end time specified, make end time = Abstime::MaxFutureTime(). format: (19980604_1200)",
default="20371231_2359", metavar="endTime")
parser.add_argument("-m", action="store", dest="mask",
help="Optional. Specifies the edit area to be used as the clip mask. If no mask was specified then the entire domain will be used. All values outside the mask will be assigned a missing value.",
metavar="mask", default="")
parser.add_argument("-t", action="store_true", dest="trim",
help="Optional. If present, trim data resolution.")
parser.add_argument("-g", action="store_true", dest="geoInfo",
help="Optional. If present, topography, latitude and longitude grids will be stored.")
parser.add_argument("-c", action="store_true", dest="compressFile",
help="Optional. If present, the netCDF file will be compressed by the gzip.")
parser.add_argument("-f", action="store", type=int, dest="compressFileFactor",
help="Optional. When provided in conjunction with the -c switch, provides the compression factor of gzip (1-9). Default is 6.",
metavar="factor", default=6)
parser.add_argument("-k", action="store_true", dest="krunch",
help="Optional. If present, the netCDF file is really shrunk, by using bytes and shorts to represent floats. Requires the -t switch.")
parser.add_argument("-C", action="store", dest="configFileName",
help="Optional. If present, controls the interval/spacing of the grids. Identifies a configuration file defining the timing constraints. The filename identifies a file within the ifpServer TEXT/Utility directory and must be a Python file.",
metavar="configIntervalFilename")
parser.add_argument("-v", action="store", dest="logFileName",
help="Optional. If present, the output from the script will be logged to the specified file. If not present, logging will default to ifpnetCDF.log located in GFESUITE_LOGDIR")
(options, args) = parser.parse_args()
options = parser.parse_args()
if options.host == None:
if "CDSHOST" in os.environ:
@ -124,22 +117,48 @@ def validateArgs():
else:
parser.error("You must specify an EDEX server port number.")
if (options.databaseID is None):
parser.error("You must specify a database id.")
return (options, args)
# must have trim, if krunch specified
if options.krunch and not options.trim:
setattr(options, "krunch", False)
return options
def createRequest():
obj = CreateNetCDFGridRequest()
wsId = WsId(progName = "ifpnetCDF")
obj.setWorkstationID(wsId)
obj.setSiteID("")
obj.setArgString(" ".join(sys.argv[1:]))
def create_request(host, port, outputFilename, parmList, databaseID, startTime,
endTime, mask, geoInfo, compressFile, configFileName,
compressFileFactor, trim, krunch, userID, logFileName):
obj = ExecuteIfpNetCDFGridRequest(outputFilename, parmList, databaseID,
startTime, endTime, mask, geoInfo, compressFile, configFileName,
compressFileFactor, trim, krunch, userID, logFileName)
return obj
def main():
log.info("Starting ifpnetCDF")
options = get_and_check_args()
log.debug("Command-line args: " + repr(options))
netCdfRequest = create_request(**vars(options))
log.debug("Sending request: " + str(netCdfRequest))
for i in range(1, RETRY_ATTEMPTS+1):
log.info("Attempt number: %d", i)
try:
thriftClient = ThriftClient.ThriftClient(options.host, options.port, "/services")
serverResponse = thriftClient.sendRequest(netCdfRequest)
except:
log.exception("Unhandled exception thrown during ifpnetCDF processing:")
sys.exit(1)
if serverResponse:
break
else:
log.error("Errors occurred during ifpnetCDF processing: " + serverResponse.message())
if (i == RETRY_ATTEMPTS):
log.error("Final attempt failed - exiting")
sys.exit(1)
if __name__ == '__main__':
main()

View file

@ -18,13 +18,18 @@
# further licensing information.
##
import logging
import os
import sys
from ufpy import ThriftClient
from ufpy import UsageArgumentParser
from ufpy.UsageArgumentParser import StoreDatabaseIDAction as StoreDatabaseIDAction
from ufpy.UsageArgumentParser import AppendParmNameAndLevelAction as AppendParmNameAndLevelAction
from dynamicserialize.dstypes.com.raytheon.uf.common.dataplugin.gfe.request import ExecuteIscMosaicRequest
from dynamicserialize.dstypes.com.raytheon.uf.common.message import WsId
from dynamicserialize import DynamicSerializationManager
import sys
import os
from ufpy.UsageOptionParser import UsageOptionParser
from ufpy import ThriftClient
#
# Provides a command-line utility to send ISC grids to GFE.
@ -35,88 +40,86 @@ from ufpy import ThriftClient
# Date Ticket# Engineer Description
# ------------ ---------- ----------- --------------------------
# 09/20/10 dgilling Initial Creation.
# 03/12/13 1759 dgilling Re-factor to use a more robust
# request object.
#
#
#
def main():
(options, args) = validateArgs()
try:
iscRequest = createRequest()
thriftClient = ThriftClient.ThriftClient(options.host, options.port, "/services")
serverResponse = thriftClient.sendRequest(iscRequest)
except Exception, e:
print "Unhandled exception thrown during iscMosaic processing: \n", str(e)
sys.exit(1)
if (not serverResponse.isOkay()):
print "Errors occurred during iscMosaic processing: ", serverResponse.message()
sys.exit(1)
def validateArgs():
logging.basicConfig(format="%(asctime)s %(name)s %(levelname)s: %(message)s",
datefmt="%H:%M:%S",
level=logging.INFO)
log = logging.getLogger('iscMosaic')
def get_args():
usage = """
%prog -h hostname -r port -d outputDatabaseID [-p parm] -f inputFile
%(prog)s -h hostname -r port -d outputDatabaseID [-p parm] -f inputFile
[-b] [-s startTime] [-e endTime] [-i parm] [-x] [-z] [-n]
[-a altMask] [-w messagePrefix] [-D gridDelay] [-o] """
parser = UsageOptionParser(usage=usage, conflict_handler="resolve")
parser.add_option("-h", action="store", type="string", dest="host",
parser = UsageArgumentParser.UsageArgumentParser(prog='iscMosaic',
usage=usage, conflict_handler="resolve")
parser.add_argument("-h", action="store", dest="host",
help="name of the ifpServer host",
metavar="hostname")
parser.add_option("-r", action="store", type="int", dest="port",
metavar="hostname", required=True)
parser.add_argument("-r", action="store", type=int, dest="port",
help="port number of the ifpServer",
metavar="port")
parser.add_option("-u", action="store", type="string", dest="user",
metavar="port", required=True)
parser.add_argument("-u", action="store", dest="userID",
help="The user ID to connect with",
metavar="userID")
parser.add_option("-d", action="store", type="string", dest="outputDatabaseID",
metavar="userID", default="SITE")
parser.add_argument("-d", action=StoreDatabaseIDAction, dest="databaseID",
help="id for output database in ifpServer",
metavar="outputDatabaseID")
parser.add_option("-p", action="append", type="string", dest="processParm",
parser.add_argument("-p", action=AppendParmNameAndLevelAction,
dest="parmsToProcess", default=[],
help="name of parm to output, can have multiple switches",
metavar="parm")
parser.add_option("-f", action="append", type="string", dest="inputFiles",
parser.add_argument("-f", action="append", dest="inFiles",
help="name of incoming netCDF files, can have multiple",
metavar="inputFile")
parser.add_option("-b", action="store_true", dest="blankOtherPeriods",
metavar="inputFile", default=[])
parser.add_argument("-b", action="store_true", dest="blankOtherPeriods",
help="blank data that does not overlap incoming grids")
parser.add_option("-s", action="store", type="string", dest="startTime",
parser.add_argument("-s", action="store", dest="startTime",
help="only output grids that occur after this YYYYMMDD_HHMM",
metavar="startTime")
parser.add_option("-e", action="store", type="string", dest="endTime",
parser.add_argument("-e", action="store", dest="endTime",
help="only output grids that occur before this YYYYMMDD_HHMM",
metavar="endTime")
parser.add_option("-x", action="store_true", dest="replaceOnly",
parser.add_argument("-x", action="store_true", dest="replaceOnly",
help="replace grids with input grids, do not perform merge")
parser.add_option("-z", action="store_true", dest="eraseFirst",
parser.add_argument("-z", action="store_true", dest="eraseFirst",
help="erase all grids in destination parm before storing")
parser.add_option("-n", action="store_true", dest="ignoreMask",
parser.add_argument("-n", action="store_true", dest="ignoreMask",
help="do not mask the grids upon storage (ignore incoming siteID)")
parser.add_option("-a", action="store", type="string", dest="altMask",
parser.add_argument("-a", action="store", dest="altMask",
help="use an alternative mask, rather than the siteID",
metavar="altMask")
parser.add_option("-w", action="store", type="string", dest="message",
parser.add_argument("-w", action="store", dest="announce",
help="alert users of data storage",
metavar="message")
parser.add_option("-k", action="store_true", dest="deleteInput",
metavar="message", default="")
parser.add_argument("-k", action="store_true", dest="deleteInput",
help="Delete the input file after processing.")
parser.add_option("-i", action="append", type="string", dest="ignoreParm",
parser.add_argument("-i", action=AppendParmNameAndLevelAction,
dest="parmsToIgnore", default=[],
help="Do not process parm by this name.",
metavar="parm")
parser.add_option("-D", action="store", type="float", dest="gridDelay",
parser.add_argument("-D", action="store", type=float, dest="gridDelay",
help="Delay between grids during processing (Default 0.00)",
metavar="gridDelay")
parser.add_option("-o", action="store_true", dest="renameWE",
metavar="gridDelay", default=0.0)
parser.add_argument("-o", action="store_true", dest="renameWE",
help="Use office type information to rename incoming data.")
parser.add_option("-S", action="store_true", dest="iscSends",
parser.add_argument("-S", action="store_true", dest="iscSends",
help="If storing in Fcst database, also force ISC send queueing.")
parser.add_option("-T", action="store_true", dest="adjustTranslate",
parser.add_argument("-T", action="store_true", dest="adjustTranslate",
help="Translate WEATHER and DISCRETE data into compatible values known by destination ifpServer.")
parser.add_option("-v", action="store_true", dest="logFile",
parser.add_argument("-v", action="store", dest="logFileName",
help="Log file destination.")
(options, args) = parser.parse_args()
options = parser.parse_args()
if options.host == None:
if "CDSHOST" in os.environ:
@ -129,29 +132,48 @@ def validateArgs():
options.port = int(os.environ["CDSPORT"])
else:
parser.error("No server port defined.")
if (options.inputFiles is None):
parser.error("-f: At least one input file must be provided.")
if (len(options.inputFiles) > 1 and options.eraseFirst):
if len(options.inFiles) > 1 and options.eraseFirst:
parser.error("Multiple input files [-f switches] and -z switch not compatible.")
if (options.ignoreMask and options.altMask is not None):
if options.ignoreMask and options.altMask is not None:
parser.error("-n and -a altMask switches are not compatible")
return (options, args)
return options
def createRequest():
obj = ExecuteIscMosaicRequest()
wsId = WsId(progName="iscMosaic")
obj.setWorkstationID(wsId)
obj.setSiteID("")
obj.setArgString(" ".join(sys.argv[1:]))
def create_request(host, port, userID, databaseID, parmsToProcess, blankOtherPeriods,
startTime, endTime, altMask, replaceOnly, eraseFirst,
announce, renameWE, iscSends, inFiles, ignoreMask,
adjustTranslate, deleteInput, parmsToIgnore, gridDelay,
logFileName):
obj = ExecuteIscMosaicRequest(userID, databaseID, parmsToProcess,
blankOtherPeriods, startTime, endTime, altMask, replaceOnly,
eraseFirst, announce, renameWE, iscSends, inFiles, ignoreMask,
adjustTranslate, deleteInput, parmsToIgnore, gridDelay, logFileName)
return obj
def main():
log.info("Starting iscMosaic")
options = get_args()
log.debug("Command-line args: " + repr(options))
iscRequest = create_request(**vars(options))
log.debug("Sending request: " + str(iscRequest))
try:
thriftClient = ThriftClient.ThriftClient(options.host, options.port, "/services")
serverResponse = thriftClient.sendRequest(iscRequest)
except:
log.exception("Unhandled exception thrown during iscMosaic processing:")
sys.exit(1)
if not serverResponse:
log.error("Errors occurred during iscMosaic processing: " + str(serverResponse.message()))
sys.exit(1)
if __name__ == '__main__':
main()

View file

@ -47,7 +47,7 @@ from ufpy.UsageArgumentParser import StoreDatabaseIDAction as StoreDatabaseIDAct
logging.basicConfig(format="%(asctime)s %(name)s %(levelname)s: %(message)s",
datefmt="%H:%M:%S",
level=logging.DEBUG)
level=logging.INFO)
log = logging.getLogger('purgeAllGrids')

View file

@ -107,16 +107,11 @@ class ParmID(object):
@staticmethod
def parmNameAndLevel(composite):
retValue = []
pos = composite.find('_')
if pos != -1:
retValue.append(composite[:pos])
retValue.append(composite[pos+1:])
return (composite[:pos], composite[pos+1:])
else:
retValue.append(composite)
retValue.append("SFC")
return retValue
return (composite, "SFC")
def __str__(self):
return self.__repr__()

View file

@ -1,47 +0,0 @@
##
# This software was developed and / or modified by Raytheon Company,
# pursuant to Contract DG133W-05-CQ-1067 with the US Government.
#
# U.S. EXPORT CONTROLLED TECHNICAL DATA
# This software product contains export-restricted data whose
# export/transfer/disclosure is restricted by U.S. law. Dissemination
# to non-U.S. persons whether in the United States or abroad requires
# an export license or other authorization.
#
# Contractor Name: Raytheon Company
# Contractor Address: 6825 Pine Street, Suite 340
# Mail Stop B8
# Omaha, NE 68106
# 402.291.0100
#
# See the AWIPS II Master Rights File ("Master Rights File.pdf") for
# further licensing information.
##
# File auto-generated against equivalent DynamicSerialize Java class
class CreateNetCDFGridRequest(object):
def __init__(self):
self.argString = None
self.workstationID = None
self.siteID = None
def getArgString(self):
return self.argString
def setArgString(self, argString):
self.argString = argString
def getWorkstationID(self):
return self.workstationID
def setWorkstationID(self, workstationID):
self.workstationID = workstationID
def getSiteID(self):
return self.siteID
def setSiteID(self, siteID):
self.siteID = siteID

View file

@ -0,0 +1,187 @@
##
# This software was developed and / or modified by Raytheon Company,
# pursuant to Contract DG133W-05-CQ-1067 with the US Government.
#
# U.S. EXPORT CONTROLLED TECHNICAL DATA
# This software product contains export-restricted data whose
# export/transfer/disclosure is restricted by U.S. law. Dissemination
# to non-U.S. persons whether in the United States or abroad requires
# an export license or other authorization.
#
# Contractor Name: Raytheon Company
# Contractor Address: 6825 Pine Street, Suite 340
# Mail Stop B8
# Omaha, NE 68106
# 402.291.0100
#
# See the AWIPS II Master Rights File ("Master Rights File.pdf") for
# further licensing information.
##
# File auto-generated against equivalent DynamicSerialize Java class
# and then modified post-generation to use AbstractGfeRequest and
# implement str(), repr()
#
# SOFTWARE HISTORY
#
# Date Ticket# Engineer Description
# ------------ ---------- ----------- --------------------------
# xx/xx/?? dgilling Initial Creation.
# 03/13/13 1759 dgilling Add software history header.
#
#
#
from dynamicserialize.dstypes.com.raytheon.uf.common.dataplugin.gfe.request import AbstractGfeRequest
from dynamicserialize.dstypes.com.raytheon.uf.common.message import WsId
class ExecuteIfpNetCDFGridRequest(AbstractGfeRequest):
def __init__(self, outputFilename=None, parmList=[], databaseID=None,
startTime=None, endTime=None, mask=None, geoInfo=False,
compressFile=False, configFileName=None, compressFileFactor=0,
trim=False, krunch=False, userID=None, logFileName=None):
super(ExecuteIfpNetCDFGridRequest, self).__init__()
self.outputFilename = outputFilename
self.parmList = parmList
self.databaseID = databaseID
self.startTime = startTime
self.endTime = endTime
self.mask = mask
self.geoInfo = geoInfo
self.compressFile = compressFile
self.configFileName = configFileName
self.compressFileFactor = compressFileFactor
self.trim = trim
self.krunch = krunch
self.userID = userID
self.logFileName = logFileName
if self.userID is not None:
self.workstationID = WsId(progName='ifpnetCDF', userName=self.userID)
if self.databaseID is not None:
self.siteID = self.databaseID.getSiteId()
def __str__(self):
retVal = "ExecuteIfpNetCDFGridRequest["
retVal += "wokstationID: " + str(self.workstationID) + ", "
retVal += "siteID: " + str(self.siteID) + ", "
retVal += "outputFilename: " + str(self.outputFilename) + ", "
retVal += "parmList: " + str(self.parmList) + ", "
retVal += "databaseID: " + str(self.databaseID) + ", "
retVal += "startTime: " + str(self.startTime) + ", "
retVal += "endTime: " + str(self.endTime) + ", "
retVal += "mask: " + str(self.mask) + ", "
retVal += "geoInfo: " + str(self.geoInfo) + ", "
retVal += "compressFile: " + str(self.compressFile) + ", "
retVal += "configFileName: " + str(self.configFileName) + ", "
retVal += "compressFileFactor: " + str(self.compressFileFactor) + ", "
retVal += "trim: " + str(self.trim) + ", "
retVal += "krunch: " + str(self.krunch) + ", "
retVal += "userID: " + str(self.userID) + ", "
retVal += "logFileName: " + str(self.logFileName) + "]"
return retVal
def __repr__(self):
retVal = "ExecuteIfpNetCDFGridRequest("
retVal += "wokstationID=" + repr(self.workstationID) + ", "
retVal += "siteID=" + repr(self.siteID) + ", "
retVal += "outputFilename=" + repr(self.outputFilename) + ", "
retVal += "parmList=" + repr(self.parmList) + ", "
retVal += "databaseID=" + repr(self.databaseID) + ", "
retVal += "startTime=" + repr(self.startTime) + ", "
retVal += "endTime=" + repr(self.endTime) + ", "
retVal += "mask=" + repr(self.mask) + ", "
retVal += "geoInfo=" + repr(self.geoInfo) + ", "
retVal += "compressFile=" + repr(self.compressFile) + ", "
retVal += "configFileName=" + repr(self.configFileName) + ", "
retVal += "compressFileFactor=" + repr(self.compressFileFactor) + ", "
retVal += "trim=" + repr(self.trim) + ", "
retVal += "krunch=" + repr(self.krunch) + ", "
retVal += "userID=" + repr(self.userID) + ", "
retVal += "logFileName=" + repr(self.logFileName) + ")"
return retVal
def getOutputFilename(self):
return self.outputFilename
def setOutputFilename(self, outputFilename):
self.outputFilename = outputFilename
def getParmList(self):
return self.parmList
def setParmList(self, parmList):
self.parmList = parmList
def getDatabaseID(self):
return self.databaseID
def setDatabaseID(self, databaseID):
self.databaseID = databaseID
def getStartTime(self):
return self.startTime
def setStartTime(self, startTime):
self.startTime = startTime
def getEndTime(self):
return self.endTime
def setEndTime(self, endTime):
self.endTime = endTime
def getMask(self):
return self.mask
def setMask(self, mask):
self.mask = mask
def getGeoInfo(self):
return self.geoInfo
def setGeoInfo(self, geoInfo):
self.geoInfo = geoInfo
def getCompressFile(self):
return self.compressFile
def setCompressFile(self, compressFile):
self.compressFile = compressFile
def getConfigFileName(self):
return self.configFileName
def setConfigFileName(self, configFileName):
self.configFileName = configFileName
def getCompressFileFactor(self):
return self.compressFileFactor
def setCompressFileFactor(self, compressFileFactor):
self.compressFileFactor = compressFileFactor
def getTrim(self):
return self.trim
def setTrim(self, trim):
self.trim = trim
def getKrunch(self):
return self.krunch
def setKrunch(self, krunch):
self.krunch = krunch
def getUserID(self):
return self.userID
def setUserID(self, userID):
self.userID = userID
def getLogFileName(self):
return self.logFileName
def setLogFileName(self, logFileName):
self.logFileName = logFileName

View file

@ -19,29 +19,216 @@
##
# File auto-generated against equivalent DynamicSerialize Java class
# and then modified post-generation to use AbstractGfeRequest and
# implement str(), repr()
#
# SOFTWARE HISTORY
#
# Date Ticket# Engineer Description
# ------------ ---------- ----------- --------------------------
# xx/xx/?? dgilling Initial Creation.
# 03/13/13 1759 dgilling Add software history header.
#
#
#
class ExecuteIscMosaicRequest(object):
def __init__(self):
self.argString = None
self.workstationID = None
self.siteID = None
from dynamicserialize.dstypes.com.raytheon.uf.common.dataplugin.gfe.request import AbstractGfeRequest
from dynamicserialize.dstypes.com.raytheon.uf.common.message import WsId
def getArgString(self):
return self.argString
class ExecuteIscMosaicRequest(AbstractGfeRequest):
def setArgString(self, argString):
self.argString = argString
def __init__(self, userID=None, databaseID=None, parmsToProcess=[],
blankOtherPeriods=False, startTime=None, endTime=None,
altMask=None, replaceOnly=False, eraseFirst=False, announce="",
renameWE=False, iscSends=False, inFiles=[], ignoreMask=False,
adjustTranslate=False, deleteInput=False, parmsToIgnore=[],
gridDelay=0.0, logFileName=None):
super(ExecuteIscMosaicRequest, self).__init__()
self.userID = userID
self.databaseID = databaseID
self.parmsToProcess = parmsToProcess
self.blankOtherPeriods = blankOtherPeriods
self.startTime = startTime
self.endTime = endTime
self.altMask = altMask
self.replaceOnly = replaceOnly
self.eraseFirst = eraseFirst
self.announce = announce
self.renameWE = renameWE
self.iscSends = iscSends
self.inFiles = inFiles
self.ignoreMask = ignoreMask
self.adjustTranslate = adjustTranslate
self.deleteInput = deleteInput
self.parmsToIgnore = parmsToIgnore
self.gridDelay = gridDelay
self.logFileName = logFileName
if self.userID is not None:
self.workstationID = WsId(progName='iscMosaic', userName=self.userID)
if self.databaseID is not None:
self.siteID = self.databaseID.getSiteId()
def __str__(self):
retVal = "ExecuteIscMosaicRequest["
retVal += "wokstationID: " + str(self.workstationID) + ", "
retVal += "siteID: " + str(self.siteID) + ", "
retVal += "userID: " + str(self.userID) + ", "
retVal += "databaseID: " + str(self.databaseID) + ", "
retVal += "parmsToProcess: " + str(self.parmsToProcess) + ", "
retVal += "blankOtherPeriods: " + str(self.blankOtherPeriods) + ", "
retVal += "startTime: " + str(self.startTime) + ", "
retVal += "endTime: " + str(self.endTime) + ", "
retVal += "altMask: " + str(self.altMask) + ", "
retVal += "replaceOnly: " + str(self.replaceOnly) + ", "
retVal += "eraseFirst: " + str(self.eraseFirst) + ", "
retVal += "announce: " + str(self.announce) + ", "
retVal += "renameWE: " + str(self.renameWE) + ", "
retVal += "iscSends: " + str(self.iscSends) + ", "
retVal += "inFiles: " + str(self.inFiles) + ", "
retVal += "ignoreMask: " + str(self.ignoreMask) + ", "
retVal += "adjustTranslate: " + str(self.adjustTranslate) + ", "
retVal += "deleteInput: " + str(self.deleteInput) + ", "
retVal += "parmsToIgnore: " + str(self.parmsToIgnore) + ", "
retVal += "gridDelay: " + str(self.gridDelay) + ", "
retVal += "logFileName: " + str(self.logFileName) + "]"
return retVal
def __repr__(self):
retVal = "ExecuteIscMosaicRequest("
retVal += "wokstationID= " + str(self.workstationID) + ", "
retVal += "siteID= " + str(self.siteID) + ", "
retVal += "userID= " + str(self.userID) + ", "
retVal += "databaseID= " + str(self.databaseID) + ", "
retVal += "parmsToProcess= " + str(self.parmsToProcess) + ", "
retVal += "blankOtherPeriods= " + str(self.blankOtherPeriods) + ", "
retVal += "startTime= " + str(self.startTime) + ", "
retVal += "endTime= " + str(self.endTime) + ", "
retVal += "altMask= " + str(self.altMask) + ", "
retVal += "replaceOnly= " + str(self.replaceOnly) + ", "
retVal += "eraseFirst= " + str(self.eraseFirst) + ", "
retVal += "announce= " + str(self.announce) + ", "
retVal += "renameWE= " + str(self.renameWE) + ", "
retVal += "iscSends= " + str(self.iscSends) + ", "
retVal += "inFiles= " + str(self.inFiles) + ", "
retVal += "ignoreMask= " + str(self.ignoreMask) + ", "
retVal += "adjustTranslate= " + str(self.adjustTranslate) + ", "
retVal += "deleteInput= " + str(self.deleteInput) + ", "
retVal += "parmsToIgnore= " + str(self.parmsToIgnore) + ", "
retVal += "gridDelay= " + str(self.gridDelay) + ", "
retVal += "logFileName= " + str(self.logFileName) + ")"
return retVal
def getWorkstationID(self):
return self.workstationID
def getUserID(self):
return self.userID
def setWorkstationID(self, workstationID):
self.workstationID = workstationID
def setUserID(self, userID):
self.userID = userID
def getSiteID(self):
return self.siteID
def getDatabaseID(self):
return self.databaseID
def setSiteID(self, siteID):
self.siteID = siteID
def setDatabaseID(self, databaseID):
self.databaseID = databaseID
def getParmsToProcess(self):
return self.parmsToProcess
def setParmsToProcess(self, parmsToProcess):
self.parmsToProcess = parmsToProcess
def getBlankOtherPeriods(self):
return self.blankOtherPeriods
def setBlankOtherPeriods(self, blankOtherPeriods):
self.blankOtherPeriods = blankOtherPeriods
def getStartTime(self):
return self.startTime
def setStartTime(self, startTime):
self.startTime = startTime
def getEndTime(self):
return self.endTime
def setEndTime(self, endTime):
self.endTime = endTime
def getAltMask(self):
return self.altMask
def setAltMask(self, altMask):
self.altMask = altMask
def getReplaceOnly(self):
return self.replaceOnly
def setReplaceOnly(self, replaceOnly):
self.replaceOnly = replaceOnly
def getEraseFirst(self):
return self.eraseFirst
def setEraseFirst(self, eraseFirst):
self.eraseFirst = eraseFirst
def getAnnounce(self):
return self.announce
def setAnnounce(self, announce):
self.announce = announce
def getRenameWE(self):
return self.renameWE
def setRenameWE(self, renameWE):
self.renameWE = renameWE
def getIscSends(self):
return self.iscSends
def setIscSends(self, iscSends):
self.iscSends = iscSends
def getInFiles(self):
return self.inFiles
def setInFiles(self, inFiles):
self.inFiles = inFiles
def getIgnoreMask(self):
return self.ignoreMask
def setIgnoreMask(self, ignoreMask):
self.ignoreMask = ignoreMask
def getAdjustTranslate(self):
return self.adjustTranslate
def setAdjustTranslate(self, adjustTranslate):
self.adjustTranslate = adjustTranslate
def getDeleteInput(self):
return self.deleteInput
def setDeleteInput(self, deleteInput):
self.deleteInput = deleteInput
def getParmsToIgnore(self):
return self.parmsToIgnore
def setParmsToIgnore(self, parmsToIgnore):
self.parmsToIgnore = parmsToIgnore
def getGridDelay(self):
return self.gridDelay
def setGridDelay(self, gridDelay):
self.gridDelay = gridDelay
def getLogFileName(self):
return self.logFileName
def setLogFileName(self, logFileName):
self.logFileName = logFileName

View file

@ -25,7 +25,7 @@ __all__ = [
'ClearPracticeVTECTableRequest',
'CommitGridsRequest',
'ConfigureTextProductsRequest',
'CreateNetCDFGridRequest',
'ExecuteIfpNetCDFGridRequest',
'ExecuteIscMosaicRequest',
'GetASCIIGridsRequest',
'GetGridDataRequest',
@ -49,11 +49,11 @@ __all__ = [
'SmartInitRequest'
]
from CommitGridsRequest import CommitGridsRequest
from AbstractGfeRequest import AbstractGfeRequest
from ClearPracticeVTECTableRequest import ClearPracticeVTECTableRequest
from CommitGridsRequest import CommitGridsRequest
from ConfigureTextProductsRequest import ConfigureTextProductsRequest
from CreateNetCDFGridRequest import CreateNetCDFGridRequest
from ExecuteIfpNetCDFGridRequest import ExecuteIfpNetCDFGridRequest
from ExecuteIscMosaicRequest import ExecuteIscMosaicRequest
from GetASCIIGridsRequest import GetASCIIGridsRequest
from GetGridDataRequest import GetGridDataRequest

View file

@ -22,6 +22,7 @@ import argparse
import sys
from dynamicserialize.dstypes.com.raytheon.uf.common.dataplugin.gfe.db.objects import DatabaseID
from dynamicserialize.dstypes.com.raytheon.uf.common.dataplugin.gfe.db.objects import ParmID
class UsageArgumentParser(argparse.ArgumentParser):
@ -43,4 +44,15 @@ class StoreDatabaseIDAction(argparse.Action):
else:
parser.error("DatabaseID [" + values + "] not a valid identifier")
class AppendParmNameAndLevelAction(argparse.Action):
def __call__(self, parser, namespace, values, option_string=None):
tx = ParmID.parmNameAndLevel(values)
comp = tx[0] + '_' + tx[1]
if (hasattr(namespace, self.dest)) and \
(getattr(namespace, self.dest) is not None):
currentValues = getattr(namespace, self.dest)
currentValues.append(comp)
setattr(namespace, self.dest, currentValues)
else:
setattr(namespace, self.dest, [comp])