From 0e07177b94bc9259f7e6c477ff6c74cf67122319 Mon Sep 17 00:00:00 2001 From: David Gillingham Date: Tue, 24 Mar 2015 10:50:27 -0500 Subject: [PATCH] Omaha #4320: Add QC check to warngen products to test that product passes through WarningDecoder without error. Change-Id: I1b5ccfafa9701cc9387a7f29459df02367c2c249 Former-commit-id: e08bcbfbd25286e547dccafbf00269c41392fccb --- .../viz/texteditor/qc/QualityControl.java | 6 +- .../texteditor/qc/WarningDecoderQCCheck.java | 96 +++++++++++++++++ .../META-INF/MANIFEST.MF | 5 +- .../WarningDecoder.py | 44 ++++---- .../res/spring/warning-request.xml | 16 +++ .../handler/VerifyProductDecodeHandler.java | 88 +++++++++++++++ .../META-INF/MANIFEST.MF | 2 + .../request/VerifyProductDecodeRequest.java | 78 ++++++++++++++ .../response/VerifyProductDecodeResponse.java | 102 ++++++++++++++++++ 9 files changed, 411 insertions(+), 26 deletions(-) create mode 100644 cave/com.raytheon.viz.texteditor/src/com/raytheon/viz/texteditor/qc/WarningDecoderQCCheck.java create mode 100644 edexOsgi/com.raytheon.edex.plugin.warning/src/com/raytheon/edex/plugin/warning/handler/VerifyProductDecodeHandler.java create mode 100644 edexOsgi/com.raytheon.uf.common.dataplugin.warning/src/com/raytheon/uf/common/dataplugin/warning/request/VerifyProductDecodeRequest.java create mode 100644 edexOsgi/com.raytheon.uf.common.dataplugin.warning/src/com/raytheon/uf/common/dataplugin/warning/response/VerifyProductDecodeResponse.java diff --git a/cave/com.raytheon.viz.texteditor/src/com/raytheon/viz/texteditor/qc/QualityControl.java b/cave/com.raytheon.viz.texteditor/src/com/raytheon/viz/texteditor/qc/QualityControl.java index fc0543c5f7..dfcc1aad19 100644 --- a/cave/com.raytheon.viz.texteditor/src/com/raytheon/viz/texteditor/qc/QualityControl.java +++ b/cave/com.raytheon.viz.texteditor/src/com/raytheon/viz/texteditor/qc/QualityControl.java @@ -49,6 +49,7 @@ import com.raytheon.uf.common.status.UFStatus.Priority; * Sep 6, 2011 10764 rferrel Use QualityControlCfg.xml for * configuable information. * Apr 29, 2013 3033 jsanchez Updated method to retrieve files in localization. + * Mar 23, 2013 4320 dgilling Integrate WarningDecoderQCCheck. * * * @@ -78,7 +79,8 @@ public class QualityControl { try { QualityControl.loadQualityControlCfg(); - String file = WarnFileUtil.convertFileContentsToString("countyTypes.txt", null, null); + String file = WarnFileUtil.convertFileContentsToString( + "countyTypes.txt", null, null); countyTypes = new HashMap(); for (String line : file.split("\n")) { String[] parts = line.split("\\\\"); @@ -131,7 +133,7 @@ public class QualityControl { IQCCheck[] checks = new IQCCheck[] { new WmoHeaderCheck(), new MndHeaderCheck(), new TextSegmentCheck(), new TimeConsistentCheck(), new CtaMarkerCheck(), - new TwoDollarCheck() }; + new TwoDollarCheck(), new WarningDecoderQCCheck() }; errorMsg = ""; for (IQCCheck check : checks) { diff --git a/cave/com.raytheon.viz.texteditor/src/com/raytheon/viz/texteditor/qc/WarningDecoderQCCheck.java b/cave/com.raytheon.viz.texteditor/src/com/raytheon/viz/texteditor/qc/WarningDecoderQCCheck.java new file mode 100644 index 0000000000..9268d9ba9e --- /dev/null +++ b/cave/com.raytheon.viz.texteditor/src/com/raytheon/viz/texteditor/qc/WarningDecoderQCCheck.java @@ -0,0 +1,96 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.viz.texteditor.qc; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; + +import com.raytheon.uf.common.dataplugin.warning.request.VerifyProductDecodeRequest; +import com.raytheon.uf.common.dataplugin.warning.response.VerifyProductDecodeResponse; +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.time.SimulatedTime; +import com.raytheon.uf.common.time.util.TimeUtil; +import com.raytheon.uf.viz.core.exception.VizException; +import com.raytheon.uf.viz.core.requests.ThriftClient; + +/** + * {@code IQCCheck} implementation that utilizes the makes a thrift request to + * decode the potential WarnGen product in the WarningDecoder to verify a + * product will successfully decode. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Mar 23, 2015  #4320     dgilling     Initial creation
+ * 
+ * 
+ * + * @author dgilling + * @version 1.0 + */ + +public final class WarningDecoderQCCheck implements IQCCheck { + + private static final IUFStatusHandler statusHandler = UFStatus + .getHandler(WarningDecoderQCCheck.class); + + /* + * (non-Javadoc) + * + * @see com.raytheon.viz.texteditor.qc.IQCCheck#runQC(java.lang.String, + * java.lang.String, java.lang.String) + */ + @Override + public String runQC(String header, String body, String nnn) { + try { + IServerRequest request = new VerifyProductDecodeRequest( + constructTextProduct(header, body)); + VerifyProductDecodeResponse response = (VerifyProductDecodeResponse) ThriftClient + .sendRequest(request); + + if (response.isSuccess()) { + return ""; + } else { + statusHandler.error("Product failed WarningDecoder QC check.\n" + + response.getErrorMessage()); + return "Product failed WarningDecoder. Check AlertViz for more information."; + } + } catch (VizException e) { + statusHandler + .error("Unable to contact EDEX server to perform WarningDecoder QC check.", + e); + return "Unable to contact EDEX server."; + } + } + + private String constructTextProduct(String header, String body) { + DateFormat wmoTimeFormat = new SimpleDateFormat("ddHHmm"); + wmoTimeFormat.setTimeZone(TimeUtil.GMT_TIME_ZONE); + String wmoTimeString = wmoTimeFormat.format(SimulatedTime + .getSystemTime().getTime()); + String fixedHeader = header.replace("DDHHMM", wmoTimeString); + return fixedHeader + "\n" + body; + } +} diff --git a/edexOsgi/com.raytheon.edex.plugin.warning/META-INF/MANIFEST.MF b/edexOsgi/com.raytheon.edex.plugin.warning/META-INF/MANIFEST.MF index 72f61e4b93..81b7a152bf 100644 --- a/edexOsgi/com.raytheon.edex.plugin.warning/META-INF/MANIFEST.MF +++ b/edexOsgi/com.raytheon.edex.plugin.warning/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: Warning Plug-in Bundle-SymbolicName: com.raytheon.edex.plugin.warning -Bundle-Version: 1.12.1174.qualifier +Bundle-Version: 1.15.0.qualifier Bundle-Vendor: RAYTHEON Require-Bundle: org.geotools, javax.persistence, @@ -15,7 +15,8 @@ Require-Bundle: org.geotools, com.raytheon.uf.common.geospatial, com.raytheon.uf.common.localization, com.raytheon.uf.common.status, - com.raytheon.uf.edex.database + com.raytheon.uf.edex.database, + com.raytheon.uf.edex.python.decoder Export-Package: com.raytheon.edex.plugin.warning.tools Bundle-RequiredExecutionEnvironment: JavaSE-1.7 Import-Package: com.raytheon.uf.common.time, diff --git a/edexOsgi/com.raytheon.edex.plugin.warning/WarningDecoder.py b/edexOsgi/com.raytheon.edex.plugin.warning/WarningDecoder.py index 82d2300a4e..53523b6c94 100644 --- a/edexOsgi/com.raytheon.edex.plugin.warning/WarningDecoder.py +++ b/edexOsgi/com.raytheon.edex.plugin.warning/WarningDecoder.py @@ -23,8 +23,6 @@ ## ## # This program decodes a product's UGC and VTEC strings -# -#
 # 
 # SOFTWARE HISTORY
 #  
@@ -45,8 +43,9 @@
 # May 15, 2014  3157     dgilling       Update location of WclInfo class.
 # Jun 10, 2014  3268     dgilling       Update location of WclInfo class.
 # Dec 17, 2014  4953     randerso       Fixed decoding of non-VTEC from command line
-
-# 
+# Mar 24, 2015 4320 dgilling Fix NullPointerException in StdWarningDecoder.__init__() +# when decoding product not from a file. +# # # @author rferrel # @version 1.0 @@ -123,24 +122,25 @@ class StdWarningDecoder(): self._rawMessage = text checkForWmo = True - # base time for decoder - warningTimestamp = TimeTools.getWarningTimestamp(self._incomingFilename) - if warningTimestamp is None : - # present time - self._time = time.time() + self._timeOffset - if WMOTimeParser.allowArchive(): - try: - yyyymmddhh = WMOTimeParser.getTimestamp(self._incomingFilename) - if len(yyyymmddhh) < 10: - timeTuple = time.strptime(yyyymmddhh, "%Y%m%d") - else : - timeTuple = time.strptime(yyyymmddhh, "%Y%m%d%H") - self._time = time.mktime(timeTuple) - except : - LogStream.logProblem('Unable to get timestamp from filename: "%s"' % (self._incomingFilename)) - else: - # Use the epoch seconds in the file generated by TextEditorDialog.java. - self._time = long(warningTimestamp) + # default time is just present time + self._time = time.time() + self._timeOffset + + if self._incomingFilename: + # base time for decoder + warningTimestamp = TimeTools.getWarningTimestamp(self._incomingFilename) + if warningTimestamp is not None: + self._time = long(warningTimestamp) + else: + if WMOTimeParser.allowArchive(): + try: + yyyymmddhh = WMOTimeParser.getTimestamp(self._incomingFilename) + if len(yyyymmddhh) < 10: + timeTuple = time.strptime(yyyymmddhh, "%Y%m%d") + else : + timeTuple = time.strptime(yyyymmddhh, "%Y%m%d%H") + self._time = time.mktime(timeTuple) + except : + LogStream.logProblem('Unable to get timestamp from filename: "%s"' % (self._incomingFilename)) os.umask(0) #ensure proper permissions diff --git a/edexOsgi/com.raytheon.edex.plugin.warning/res/spring/warning-request.xml b/edexOsgi/com.raytheon.edex.plugin.warning/res/spring/warning-request.xml index 28860d3bb6..7ca09eaa05 100644 --- a/edexOsgi/com.raytheon.edex.plugin.warning/res/spring/warning-request.xml +++ b/edexOsgi/com.raytheon.edex.plugin.warning/res/spring/warning-request.xml @@ -22,6 +22,22 @@ + + + + + + + + + + + + + + + + + * + * SOFTWARE HISTORY + * + * Date Ticket# Engineer Description + * ------------ ---------- ----------- -------------------------- + * Mar 23, 2015 #4320 dgilling Initial creation + * + * + * + * @author dgilling + * @version 1.0 + */ + +public final class VerifyProductDecodeHandler implements + IRequestHandler { + + private final PythonDecoder decoder; + + /** + * Constructor for this request handler. Intended to be called via + * spring/camel. + * + * @param decoder + * {@code PythonDecoder} instance to use for decoding + * verification. + */ + public VerifyProductDecodeHandler(final PythonDecoder decoder) { + this.decoder = decoder; + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.common.serialization.comm.IRequestHandler#handleRequest + * (com.raytheon.uf.common.serialization.comm.IServerRequest) + */ + @Override + public VerifyProductDecodeResponse handleRequest( + VerifyProductDecodeRequest request) throws Exception { + try { + Map decoderArgs = new HashMap<>(1, 1f); + decoderArgs.put("text", request.getProductText()); + decoder.decode(decoderArgs); + } catch (Exception e) { + return new VerifyProductDecodeResponse(false, + e.getLocalizedMessage()); + } + + return new VerifyProductDecodeResponse(true); + } +} diff --git a/edexOsgi/com.raytheon.uf.common.dataplugin.warning/META-INF/MANIFEST.MF b/edexOsgi/com.raytheon.uf.common.dataplugin.warning/META-INF/MANIFEST.MF index 071ca36e9b..28df832155 100644 --- a/edexOsgi/com.raytheon.uf.common.dataplugin.warning/META-INF/MANIFEST.MF +++ b/edexOsgi/com.raytheon.uf.common.dataplugin.warning/META-INF/MANIFEST.MF @@ -9,6 +9,8 @@ Export-Package: com.raytheon.uf.common.dataplugin.warning, com.raytheon.uf.common.dataplugin.warning.config, com.raytheon.uf.common.dataplugin.warning.gis, com.raytheon.uf.common.dataplugin.warning.portions, + com.raytheon.uf.common.dataplugin.warning.request, + com.raytheon.uf.common.dataplugin.warning.response, com.raytheon.uf.common.dataplugin.warning.util Import-Package: com.raytheon.uf.common.time, javax.persistence, diff --git a/edexOsgi/com.raytheon.uf.common.dataplugin.warning/src/com/raytheon/uf/common/dataplugin/warning/request/VerifyProductDecodeRequest.java b/edexOsgi/com.raytheon.uf.common.dataplugin.warning/src/com/raytheon/uf/common/dataplugin/warning/request/VerifyProductDecodeRequest.java new file mode 100644 index 0000000000..0ed4e03a34 --- /dev/null +++ b/edexOsgi/com.raytheon.uf.common.dataplugin.warning/src/com/raytheon/uf/common/dataplugin/warning/request/VerifyProductDecodeRequest.java @@ -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.uf.common.dataplugin.warning.request; + +import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; +import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; +import com.raytheon.uf.common.serialization.comm.IServerRequest; + +/** + * {@code IServerRequest} to verify the specified raw message for a warning + * product successfully can be decoded by the WarningDecoder. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Mar 23, 2015  #4320     dgilling     Initial creation
+ * 
+ * 
+ * + * @author dgilling + * @version 1.0 + */ +@DynamicSerialize +public final class VerifyProductDecodeRequest implements IServerRequest { + + @DynamicSerializeElement + private String productText; + + /** + * Default constructor--should only be used by DynamicSerialize. + */ + public VerifyProductDecodeRequest() { + + } + + /** + * Build a request with the specified raw message. + * + * @param productText + * Raw message of the warning product to test through decoder. + */ + public VerifyProductDecodeRequest(String productText) { + this.productText = productText; + } + + @Override + public String toString() { + return "VerifyProductDecodeRequest [productText=" + productText + "]"; + } + + public String getProductText() { + return productText; + } + + public void setProductText(String productText) { + this.productText = productText; + } +} diff --git a/edexOsgi/com.raytheon.uf.common.dataplugin.warning/src/com/raytheon/uf/common/dataplugin/warning/response/VerifyProductDecodeResponse.java b/edexOsgi/com.raytheon.uf.common.dataplugin.warning/src/com/raytheon/uf/common/dataplugin/warning/response/VerifyProductDecodeResponse.java new file mode 100644 index 0000000000..164a4a6261 --- /dev/null +++ b/edexOsgi/com.raytheon.uf.common.dataplugin.warning/src/com/raytheon/uf/common/dataplugin/warning/response/VerifyProductDecodeResponse.java @@ -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.uf.common.dataplugin.warning.response; + +import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; +import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; + +/** + * Response sent from EDEX when making a {@code VerifyProductDecodeRequest}. + * Tells requestor whether product successfully decoder, and if it failed, the + * error trace returned by the decoder. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Mar 23, 2015  #4320     dgilling     Initial creation
+ * 
+ * 
+ * + * @author dgilling + * @version 1.0 + */ +@DynamicSerialize +public final class VerifyProductDecodeResponse { + + @DynamicSerializeElement + private boolean success; + + @DynamicSerializeElement + private String errorMessage; + + /** + * Default constructor--should only be used by DynamicSerialize. + */ + public VerifyProductDecodeResponse() { + } + + /** + * Build a response with the specified success value. + * + * @param success + * Whether or not product successfully decoded. + */ + public VerifyProductDecodeResponse(boolean success) { + this(success, ""); + } + + /** + * Build a response with specified success value and error message. + * + * @param success + * Whether or not product successfully decoded. + * @param errorMessage + * Error message returned by decoder. + */ + public VerifyProductDecodeResponse(boolean success, String errorMessage) { + this.success = success; + this.errorMessage = errorMessage; + } + + @Override + public String toString() { + return "VerifyProductDecodeResponse [success=" + success + + ", errorMessage=" + errorMessage + "]"; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public String getErrorMessage() { + return errorMessage; + } + + public void setErrorMessage(String errorMessage) { + this.errorMessage = errorMessage; + } +}