Omaha #4806: Create method so GFE smart tools and procedures can transmit text products.

Change-Id: Iada380912df9cabf744eb004d1f260713a62db7b

Former-commit-id: b96f462d21b1483e34b36533abfb27e2fb9e5f74
This commit is contained in:
David Gillingham 2015-08-28 13:32:53 -05:00
parent e16ebbae02
commit 534d43b455
3 changed files with 245 additions and 101 deletions

View file

@ -72,6 +72,7 @@
# Aug 26, 2015 4809 randerso Added option group parameter to editAreaList() # Aug 26, 2015 4809 randerso Added option group parameter to editAreaList()
# Aug 26, 2015 4804 dgilling Added callTextFormatter(). # Aug 26, 2015 4804 dgilling Added callTextFormatter().
# Aug 27, 2015 4805 dgilling Added saveCombinationsFile(). # Aug 27, 2015 4805 dgilling Added saveCombinationsFile().
# Aug 27, 2015 4806 dgilling Added transmitTextProduct().
######################################################################## ########################################################################
import types, string, time, sys import types, string, time, sys
from math import * from math import *
@ -108,6 +109,7 @@ from com.raytheon.viz.gfe.dialogs.formatterlauncher import ConfigData
ProductStateEnum = ConfigData.ProductStateEnum ProductStateEnum = ConfigData.ProductStateEnum
from com.raytheon.viz.gfe.textformatter import FormatterUtil from com.raytheon.viz.gfe.textformatter import FormatterUtil
from com.raytheon.viz.gfe.textformatter import TextProductFinishWaiter from com.raytheon.viz.gfe.textformatter import TextProductFinishWaiter
from com.raytheon.viz.gfe.textformatter import TextProductTransmitter
class SmartScript(BaseTool.BaseTool): class SmartScript(BaseTool.BaseTool):
@ -2639,7 +2641,6 @@ class SmartScript(BaseTool.BaseTool):
". Check formatter logs from Process Monitor for more information." ". Check formatter logs from Process Monitor for more information."
raise RuntimeError(msg) raise RuntimeError(msg)
return product return product
def saveCombinationsFile(self, name, combinations): def saveCombinationsFile(self, name, combinations):
""" """
@ -2665,3 +2666,27 @@ class SmartScript(BaseTool.BaseTool):
combo_list = JUtil.pyValToJavaObj([[str(zone) for zone in group] for group in combinations]) combo_list = JUtil.pyValToJavaObj([[str(zone) for zone in group] for group in combinations])
CombinationsFileUtil.generateAutoCombinationsFile(combo_list, str(name)) CombinationsFileUtil.generateAutoCombinationsFile(combo_list, str(name))
def transmitTextProduct(self, product, wanPil, wmoType):
"""
Transmit the specified product. Will automatically detect if GFE is
operating in OPERATIONAL or PRACTICE mode and send using the appropriate
route.
Args:
product: the text or body of the product to transmit.
wanPil: the AWIPS WAN PIL for the product
wmoType: The WMO type of the product.
Returns:
The status of the transmission request as a ProductStateEnum.
"""
wanPil = str(wanPil)
product = str(product)
wmoType = str(wmoType)
transmitter = TextProductTransmitter(product, wanPil, wmoType)
practice = self.gfeOperatingMode()=="PRACTICE"
status = transmitter.transmitProduct(practice)
return status

View file

@ -19,11 +19,9 @@
**/ **/
package com.raytheon.viz.gfe.dialogs.formatterlauncher; package com.raytheon.viz.gfe.dialogs.formatterlauncher;
import java.text.SimpleDateFormat;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.TimeZone;
import org.eclipse.swt.SWT; import org.eclipse.swt.SWT;
import org.eclipse.swt.events.DisposeEvent; import org.eclipse.swt.events.DisposeEvent;
@ -40,23 +38,15 @@ import org.eclipse.swt.widgets.ProgressBar;
import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text; import org.eclipse.swt.widgets.Text;
import com.raytheon.uf.common.activetable.SendPracticeProductRequest;
import com.raytheon.uf.common.activetable.response.GetNextEtnResponse; import com.raytheon.uf.common.activetable.response.GetNextEtnResponse;
import com.raytheon.uf.common.dissemination.OUPRequest;
import com.raytheon.uf.common.dissemination.OUPResponse;
import com.raytheon.uf.common.dissemination.OfficialUserProduct;
import com.raytheon.uf.common.serialization.comm.IServerRequest;
import com.raytheon.uf.common.status.IUFStatusHandler; import com.raytheon.uf.common.status.IUFStatusHandler;
import com.raytheon.uf.common.status.UFStatus; import com.raytheon.uf.common.status.UFStatus;
import com.raytheon.uf.common.status.UFStatus.Priority; import com.raytheon.uf.common.status.UFStatus.Priority;
import com.raytheon.uf.common.time.SimulatedTime;
import com.raytheon.uf.common.time.TimeRange; import com.raytheon.uf.common.time.TimeRange;
import com.raytheon.uf.common.time.util.TimeUtil;
import com.raytheon.uf.viz.core.auth.UserController;
import com.raytheon.uf.viz.core.exception.VizException; import com.raytheon.uf.viz.core.exception.VizException;
import com.raytheon.uf.viz.core.requests.ThriftClient;
import com.raytheon.viz.core.mode.CAVEMode; import com.raytheon.viz.core.mode.CAVEMode;
import com.raytheon.viz.gfe.product.TextDBUtil; import com.raytheon.viz.gfe.product.TextDBUtil;
import com.raytheon.viz.gfe.textformatter.TextProductTransmitter;
import com.raytheon.viz.gfe.vtec.GFEVtecUtil; import com.raytheon.viz.gfe.vtec.GFEVtecUtil;
import com.raytheon.viz.texteditor.util.VtecObject; import com.raytheon.viz.texteditor.util.VtecObject;
import com.raytheon.viz.ui.dialogs.CaveSWTDialog; import com.raytheon.viz.ui.dialogs.CaveSWTDialog;
@ -89,6 +79,8 @@ import com.raytheon.viz.ui.dialogs.CaveSWTDialog;
* Feb 26, 2015 4126 randerso Ensure transmit/store is properly cancelled if dialog is closed * Feb 26, 2015 4126 randerso Ensure transmit/store is properly cancelled if dialog is closed
* Code cleanup * Code cleanup
* Apr 20, 2015 4027 randerso Renamed ProductStateEnum with an initial capital * Apr 20, 2015 4027 randerso Renamed ProductStateEnum with an initial capital
* Aug 28, 2015 4806 dgilling Extract code for product transmission into
* its own class.
* *
* </pre> * </pre>
* *
@ -102,8 +94,6 @@ public class StoreTransmitDlg extends CaveSWTDialog {
private static final transient IUFStatusHandler statusHandler = UFStatus private static final transient IUFStatusHandler statusHandler = UFStatus
.getHandler(StoreTransmitDlg.class); .getHandler(StoreTransmitDlg.class);
private static int SEQ_NUMBER = 0;
/** /**
* Product ID text control. * Product ID text control.
*/ */
@ -529,93 +519,14 @@ public class StoreTransmitDlg extends CaveSWTDialog {
* true if we are transmitting a practice product * true if we are transmitting a practice product
*/ */
private void transmitProduct(boolean practice) { private void transmitProduct(boolean practice) {
IServerRequest req = null;
if (practice) {
SendPracticeProductRequest practiceReq = new SendPracticeProductRequest();
practiceReq.setNotifyGFE(true);
practiceReq.setProductText(productText);
if (!SimulatedTime.getSystemTime().isRealTime()) {
SimpleDateFormat dateFormatter = new SimpleDateFormat(
"yyyyMMdd_HHmm");
dateFormatter.setTimeZone(TimeZone.getTimeZone("GMT"));
practiceReq.setDrtString(dateFormatter.format(SimulatedTime
.getSystemTime().getTime()));
}
req = practiceReq;
} else {
OUPRequest oupReq = new OUPRequest();
OfficialUserProduct oup = new OfficialUserProduct();
// make sure the awipsWanPil is exactly 10 characters space-padded
// long
String awipsWanPil = String.format("%-10s", productIdText.getText()
.trim());
oup.setAwipsWanPil(awipsWanPil);
oup.setProductText(productText);
String tempName = awipsWanPil + "-" + SEQ_NUMBER + "-"
+ (System.currentTimeMillis() / TimeUtil.MILLIS_PER_SECOND);
oup.setFilename(tempName);
String type = parentEditor.getProductType();
if (!type.equals("rou") && !type.equals("res")) {
oup.setWmoType(type);
}
// oup.setAddress(parentEditor.getAutoSendAddress());
oup.setNeedsWmoHeader(false);
oup.setSource("GFE");
oupReq.setProduct(oup);
oupReq.setUser(UserController.getUserObject());
req = oupReq;
}
try { try {
Object response = ThriftClient.sendRequest(req); TextProductTransmitter transmitter = new TextProductTransmitter(
// TODO need a response on the other one? productText, productIdText.getText(),
// it's going async.... parentEditor.getProductType());
if (response instanceof OUPResponse) { ConfigData.ProductStateEnum state = transmitter
OUPResponse resp = (OUPResponse) response; .transmitProduct(practice);
Priority p = null;
if (!resp.hasFailure()) {
p = Priority.EVENTA;
sendTransmissionStatus(ConfigData.ProductStateEnum.Transmitted);
} else {
// determine the failure type and priority
ConfigData.ProductStateEnum state = null;
if (resp.isSendLocalSuccess()) {
state = ConfigData.ProductStateEnum.Transmitted;
} else {
state = ConfigData.ProductStateEnum.Failed;
}
p = Priority.EVENTA;
if (!resp.isAttempted()) {
// if was never attempted to send or store even locally
p = Priority.CRITICAL;
} else if (!resp.isSendLocalSuccess()) {
// if send/store locally failed
p = Priority.CRITICAL;
} else if (!resp.isSendWANSuccess()) {
// if send to WAN failed
if (resp.getNeedAcknowledgment()) {
// if ack was needed, if it never sent then no ack
// was recieved
p = Priority.CRITICAL;
} else {
// if no ack was needed
p = Priority.EVENTA;
}
} else if (resp.getNeedAcknowledgment()
&& !resp.isAcknowledged()) {
// if sent but not acknowledged when acknowledgment is
// needed
p = Priority.CRITICAL;
}
sendTransmissionStatus(state);
}
statusHandler.handle(p, resp.getMessage());
}
sendTransmissionStatus(state);
this.parentEditor.setProductText(productText, false); this.parentEditor.setProductText(productText, false);
this.parentEditor.brain(); this.parentEditor.brain();
} catch (VizException e) { } catch (VizException e) {
@ -623,8 +534,6 @@ public class StoreTransmitDlg extends CaveSWTDialog {
sendTransmissionStatus(ConfigData.ProductStateEnum.Failed); sendTransmissionStatus(ConfigData.ProductStateEnum.Failed);
this.parentEditor.revive(); this.parentEditor.revive();
} }
SEQ_NUMBER++;
} }
private void sendTransmissionStatus(ConfigData.ProductStateEnum status) { private void sendTransmissionStatus(ConfigData.ProductStateEnum status) {

View file

@ -0,0 +1,210 @@
/**
* 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.viz.gfe.textformatter;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.TimeZone;
import java.util.concurrent.atomic.AtomicInteger;
import com.raytheon.uf.common.activetable.SendPracticeProductRequest;
import com.raytheon.uf.common.dataplugin.text.db.MixedCaseProductSupport;
import com.raytheon.uf.common.dissemination.OUPRequest;
import com.raytheon.uf.common.dissemination.OUPResponse;
import com.raytheon.uf.common.dissemination.OfficialUserProduct;
import com.raytheon.uf.common.serialization.comm.IServerRequest;
import com.raytheon.uf.common.status.IUFStatusHandler;
import com.raytheon.uf.common.status.UFStatus;
import com.raytheon.uf.common.status.UFStatus.Priority;
import com.raytheon.uf.common.time.SimulatedTime;
import com.raytheon.uf.common.time.util.TimeUtil;
import com.raytheon.uf.viz.core.auth.UserController;
import com.raytheon.uf.viz.core.exception.VizException;
import com.raytheon.uf.viz.core.requests.ThriftClient;
import com.raytheon.viz.gfe.dialogs.formatterlauncher.ConfigData;
import com.raytheon.viz.gfe.dialogs.formatterlauncher.ConfigData.ProductStateEnum;
/**
* Handles product transmission for GFE text products, using handleOUP for
* operational products and the {@code SendPracticeProduct} thrift request for
* practice products.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Aug 28, 2015 #4806 dgilling Initial creation
*
* </pre>
*
* @author dgilling
* @version 1.0
*/
public final class TextProductTransmitter {
private static final transient IUFStatusHandler statusHandler = UFStatus
.getHandler(TextProductTransmitter.class);
private static final AtomicInteger SEQ_NUMBER = new AtomicInteger();
private final String productText;
private final String pil;
private final String wmoType;
/**
* Constructor
*
* @param productText
* Product text to transmit
* @param pil
* AWIPS WAN PIL of the product to transmit
* @param wmoType
* WMO type for the product.
*/
public TextProductTransmitter(String productText, String pil, String wmoType) {
this.pil = pil;
this.productText = MixedCaseProductSupport.conditionalToUpper(
this.pil.substring(4, 7), productText);
this.wmoType = wmoType;
}
/**
* Transmit the product.
*
* @param practice
* Whether to transmit the product as an operational or practice
* product.
* @return Product transmission status.
* @throws VizException
* If the transmission request threw an exception during
* server-side processing.
*/
public ProductStateEnum transmitProduct(boolean practice)
throws VizException {
IServerRequest req = (!practice) ? constructOperationalRequest()
: constructPracticeRequest();
Object response = ThriftClient.sendRequest(req);
/*
* Currently processing of the practice product happens async, so as
* long as the request didn't throw an exception, we can only assume it
* succeeded.
*/
ProductStateEnum status = (response instanceof OUPResponse) ? processOupResponse((OUPResponse) response)
: ProductStateEnum.Transmitted;
return status;
}
private SendPracticeProductRequest constructPracticeRequest() {
SendPracticeProductRequest practiceReq = new SendPracticeProductRequest();
practiceReq.setNotifyGFE(true);
practiceReq.setProductText(productText);
practiceReq.setDrtString(getDRTString());
return practiceReq;
}
private OUPRequest constructOperationalRequest() {
OfficialUserProduct oup = new OfficialUserProduct();
oup.setProductText(productText);
/*
* ensure the awipsWanPil is exactly 10 characters space-padded long
*/
String awipsWanPil = String.format("%-10s", pil.trim());
oup.setAwipsWanPil(awipsWanPil);
String tempName = awipsWanPil + "-" + SEQ_NUMBER.incrementAndGet()
+ "-"
+ (System.currentTimeMillis() / TimeUtil.MILLIS_PER_SECOND);
oup.setFilename(tempName);
if (!wmoType.equals("rou") && !wmoType.equals("res")) {
oup.setWmoType(wmoType);
}
oup.setNeedsWmoHeader(false);
oup.setSource("GFE");
OUPRequest oupReq = new OUPRequest();
oupReq.setProduct(oup);
oupReq.setUser(UserController.getUserObject());
return oupReq;
}
private ProductStateEnum processOupResponse(OUPResponse response) {
ProductStateEnum retVal = null;
if (response instanceof OUPResponse) {
OUPResponse resp = response;
Priority p = null;
if (!resp.hasFailure()) {
p = Priority.EVENTA;
retVal = ConfigData.ProductStateEnum.Transmitted;
} else {
// determine the failure type and priority
if (resp.isSendLocalSuccess()) {
retVal = ConfigData.ProductStateEnum.Transmitted;
} else {
retVal = ConfigData.ProductStateEnum.Failed;
}
p = Priority.EVENTA;
if (!resp.isAttempted()) {
// if was never attempted to send or store even locally
p = Priority.CRITICAL;
} else if (!resp.isSendLocalSuccess()) {
// if send/store locally failed
p = Priority.CRITICAL;
} else if (!resp.isSendWANSuccess()) {
// if send to WAN failed
if (resp.getNeedAcknowledgment()) {
// if ack was needed, if it never sent then no ack
// was recieved
p = Priority.CRITICAL;
} else {
// if no ack was needed
p = Priority.EVENTA;
}
} else if (resp.getNeedAcknowledgment()
&& !resp.isAcknowledged()) {
// if sent but not acknowledged when acknowledgment is
// needed
p = Priority.CRITICAL;
}
}
statusHandler.handle(p, resp.getMessage());
}
return retVal;
}
private static String getDRTString() {
String time = null;
if (!SimulatedTime.getSystemTime().isRealTime()) {
DateFormat gmtFormatter = new SimpleDateFormat("yyyyMMdd_HHmm");
gmtFormatter.setTimeZone(TimeZone.getTimeZone("GMT"));
time = gmtFormatter.format(SimulatedTime.getSystemTime().getTime());
}
return time;
}
}