Omaha #4320: Add QC check to warngen products to test that product passes through WarningDecoder without error.

Change-Id: I1b5ccfafa9701cc9387a7f29459df02367c2c249

Former-commit-id: e08bcbfbd25286e547dccafbf00269c41392fccb
This commit is contained in:
David Gillingham 2015-03-24 10:50:27 -05:00 committed by Gerrit Code Review
parent cdd4141d18
commit 0e07177b94
9 changed files with 411 additions and 26 deletions

View file

@ -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.
*
* </pre>
*
@ -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<String, String>();
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) {

View file

@ -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.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Mar 23, 2015 #4320 dgilling Initial creation
*
* </pre>
*
* @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;
}
}

View file

@ -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,

View file

@ -23,8 +23,6 @@
##
##
# This program decodes a product's UGC and VTEC strings
#
# <pre>
#
# 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
# </pre>
# 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

View file

@ -22,6 +22,22 @@
<constructor-arg value="com.raytheon.uf.common.dataplugin.warning.gis.GenerateGeospatialTimeSetRequest"/>
<constructor-arg ref="generateGeospatialTimeSetHandler"/>
</bean>
<bean id="warningDecodeVerifier" class="com.raytheon.uf.edex.python.decoder.PythonDecoder">
<property name="pluginName" value="warning"/>
<property name="pluginFQN" value="com.raytheon.edex.plugin.warning"/>
<property name="moduleName" value="WarningDecoder"/>
<property name="cache" value="false"/>
<property name="recordClassname" value="com.raytheon.uf.common.dataplugin.warning.WarningRecord"/>
</bean>
<bean id="VerifyProductDecodeHandler" class="com.raytheon.edex.plugin.warning.handler.VerifyProductDecodeHandler">
<constructor-arg ref="warningDecodeVerifier" />
</bean>
<bean factory-bean="handlerRegistry" factory-method="register">
<constructor-arg value="com.raytheon.uf.common.dataplugin.warning.request.VerifyProductDecodeRequest" />
<constructor-arg ref="VerifyProductDecodeHandler" />
</bean>
<camelContext id="geospatialDataGenerator-camel"
xmlns="http://camel.apache.org/schema/spring"

View file

@ -0,0 +1,88 @@
/**
* 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.warning.handler;
import java.util.HashMap;
import java.util.Map;
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.IRequestHandler;
import com.raytheon.uf.edex.python.decoder.PythonDecoder;
/**
* Request handler for {@code VerifyProductDecodeRequest}. Takes specified raw
* message and runs it through the WarningDecoder (injected via spring/camel)
* and verifies the product successfully decodes. Returns error trace from
* decoder if it fails.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Mar 23, 2015 #4320 dgilling Initial creation
*
* </pre>
*
* @author dgilling
* @version 1.0
*/
public final class VerifyProductDecodeHandler implements
IRequestHandler<VerifyProductDecodeRequest> {
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<String, Object> 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);
}
}

View file

@ -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,

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.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.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Mar 23, 2015 #4320 dgilling Initial creation
*
* </pre>
*
* @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;
}
}

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.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.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Mar 23, 2015 #4320 dgilling Initial creation
*
* </pre>
*
* @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;
}
}