Issue #2971 - Added condition to avoid malformed parts in the message.

Change-Id: Ic8e7351faad4e1b65939d568d307ec5a4789f4ec

Former-commit-id: 042014c2a7 [formerly 4afbf3339470bec70c0cb958a0379c48c6103fd3]
Former-commit-id: 1dce366e88
This commit is contained in:
Slav Korolev 2014-04-07 14:54:57 -04:00
parent 69c6217ae9
commit c53687c5ec
6 changed files with 181 additions and 76 deletions

View file

@ -22,5 +22,5 @@
<regex>^(W[FGHOTUW]|FZ)[ACHKMPU][AHKQSWY].*</regex>
<regex>^(WT)(NT|PZ)\d{2} KNHC.*</regex>
<regex>^(WTP)A\d{2} PHFO.*</regex>
<regex>^(NWU)S\d{2} KWNS.*</regex>
<regex>^NWUS([13-9]\\d|2[1-9]) KWNS.*</regex>
</requestPatterns>

View file

@ -22,17 +22,16 @@ package com.raytheon.uf.edex.plugin.svrwx;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.raytheon.edex.esb.Headers;
import com.raytheon.uf.common.dataplugin.PluginDataObject;
import com.raytheon.uf.common.dataplugin.svrwx.SvrWxRecord;
import com.raytheon.uf.common.pointdata.PointDataDescription;
import com.raytheon.uf.common.status.IUFStatusHandler;
import com.raytheon.uf.common.status.UFStatus;
import com.raytheon.uf.edex.plugin.svrwx.decoder.SvrWxParser;
/**
*
* SvrWx Decoder.
*
* <pre>
*
@ -47,7 +46,8 @@ import com.raytheon.uf.edex.plugin.svrwx.decoder.SvrWxParser;
* @version 1.0
*/
public class SvrWxDecoder {
private Log logger = LogFactory.getLog(getClass());
private static IUFStatusHandler logger = UFStatus
.getHandler(SvrWxDecoder.class);
private final String pluginName;
@ -84,10 +84,11 @@ public class SvrWxDecoder {
}
/**
* Decoded input data.
*
* @param data
* @param headers
* @return
* @return decodedData
*/
public PluginDataObject[] decode(byte[] data, Headers headers) {
@ -131,7 +132,6 @@ public class SvrWxDecoder {
logger.info(traceId + "- No data in file");
decodedData = new PluginDataObject[0];
}
return decodedData;
}

View file

@ -26,9 +26,8 @@ import com.raytheon.uf.common.dataplugin.svrwx.SvrWxRecord;
import com.raytheon.uf.edex.database.DataAccessLayerException;
import com.raytheon.uf.edex.pointdata.PointDataPluginDao;
/**
*
* SvrWxRecord Dao
*
* <pre>
*
@ -37,6 +36,7 @@ import com.raytheon.uf.edex.pointdata.PointDataPluginDao;
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Jan 4, 2010 jsanchez Initial creation
* Apr 10, 2014 2971 skorolev Cleaned code.
*
* </pre>
*
@ -47,6 +47,8 @@ import com.raytheon.uf.edex.pointdata.PointDataPluginDao;
public class SvrWxRecordDao extends PointDataPluginDao<SvrWxRecord> {
/**
* Creates a new TropicalCycloneGuidance Dao
*
* @param pluginName
* @throws PluginException
*/
public SvrWxRecordDao(String pluginName) throws PluginException {
@ -73,6 +75,7 @@ public class SvrWxRecordDao extends PointDataPluginDao<SvrWxRecord> {
}
return report;
}
/**
* Queries for to determine if a given data uri exists on the tcg table.
*
@ -91,16 +94,35 @@ public class SvrWxRecordDao extends PointDataPluginDao<SvrWxRecord> {
return results;
}
/*
* (non-Javadoc)
*
* @see
* com.raytheon.uf.edex.pointdata.PointDataPluginDao#getKeysRequiredForFileName
* ()
*/
@Override
public String[] getKeysRequiredForFileName() {
return new String[] { "dataTime.refTime" };
}
/*
* (non-Javadoc)
*
* @see
* com.raytheon.uf.edex.pointdata.PointDataPluginDao#getPointDataFileName
* (com.raytheon.uf.common.dataplugin.PluginDataObject)
*/
@Override
public String getPointDataFileName(SvrWxRecord p) {
return "svrwx.h5";
}
/*
* (non-Javadoc)
*
* @see com.raytheon.uf.edex.pointdata.PointDataPluginDao#newObject()
*/
@Override
public SvrWxRecord newObject() {
return new SvrWxRecord();

View file

@ -28,11 +28,11 @@ import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.raytheon.uf.common.status.IUFStatusHandler;
import com.raytheon.uf.common.status.UFStatus;
/**
* TODO Add Description
* Internal Report
*
* <pre>
*
@ -41,6 +41,7 @@ import org.apache.commons.logging.LogFactory;
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Jan 10, 2010 jsanchez Initial creation
* Apr 10, 2014 2971 skorolev Cleaned code.
*
* </pre>
*
@ -49,10 +50,14 @@ import org.apache.commons.logging.LogFactory;
*/
public class InternalReport {
private static Log logger = LogFactory.getLog(InternalReport.class);
private static IUFStatusHandler logger = UFStatus
.getHandler(InternalReport.class);
public static final String REPORT_TYPE_LN = "^((.*)(TORNADO REPORTS|LRG HAIL/STRONG WIND RPTS|OTHER SEVERE REPORTS)(.*))";
private static final Pattern REPORT_TYPE_LN_PTRN = Pattern
.compile(REPORT_TYPE_LN);
public static final String EVENT_KEY = "(\\*TORN|WNDG|([AG]\\s{0,1}\\d{2,3}))";
public static final String TIME = "(\\d{1,2}/\\d{4,4})";
@ -60,6 +65,8 @@ public class InternalReport {
public static final String EVENT_LN = "^((.*)" + EVENT_KEY + "(.*)" + TIME
+ ")";
private static final Pattern EVENT_LN_PTRN = Pattern.compile(EVENT_LN);
public static final String LATLON = "(\\d{4,4}\\s{0,1}\\d{4,5})";
public static final String STATIONID = "(\\w{3,3}/\\w{3,3})";
@ -67,23 +74,35 @@ public class InternalReport {
public static final String RMK_LN = "^((.*)" + STATIONID + "(.*)" + LATLON
+ ")";
private static final Pattern RMK_LN_PTRN = Pattern.compile(RMK_LN);
public static final String REFTIME = "(\\d{2,2}CST\\s\\w{3,3}\\s\\w{3,3}\\s{1,2}\\d{1,2}\\s{1,2}\\d{4,4})";
public static final String TIME_RANGE_LN = "^((.*)FOR\\s" + REFTIME
+ "\\sTHRU\\s" + REFTIME + ")";
private static final Pattern TIME_RANGE_LN_PTRN = Pattern
.compile(TIME_RANGE_LN);
private final InternalType lineType;
private final String reportLine;
private List<InternalReport> subLines = null;
/**
*
* @param type
* @param line
*/
public InternalReport(InternalType type, String line) {
lineType = type;
reportLine = line;
}
/**
* Get Line Type.
*
* @return the lineType
*/
public InternalType getLineType() {
@ -91,6 +110,8 @@ public class InternalReport {
}
/**
* Get Report Line.
*
* @return the reportLine
*/
public String getReportLine() {
@ -98,6 +119,7 @@ public class InternalReport {
}
/**
* Get SubLines.
*
* @return
*/
@ -141,21 +163,23 @@ public class InternalReport {
return sb.toString();
}
/**
* Message identification.
*
* @param message
* @return
*/
public static List<InternalReport> identifyMessage(byte[] message) {
List<InternalReport> reports = new ArrayList<InternalReport>();
List<String> lines = separateLines(message);
if (lines != null) {
Pattern p1 = Pattern.compile(REPORT_TYPE_LN);
Pattern p2 = Pattern.compile(EVENT_LN);
Pattern p3 = Pattern.compile(RMK_LN);
Pattern p4 = Pattern.compile(TIME_RANGE_LN);
InternalType t1 = InternalType.REPORT_TYPE;
InternalType t2 = InternalType.EVENT_LN;
InternalType t3 = InternalType.REMARKS;
InternalType t4 = InternalType.TIME_RANGE;
Pattern patterns[] = { p1, p2, p3, p4 };
Pattern patterns[] = { REPORT_TYPE_LN_PTRN, EVENT_LN_PTRN,
RMK_LN_PTRN, TIME_RANGE_LN_PTRN };
InternalType types[] = { t1, t2, t3, t4 };
boolean found;
for (String s : lines) {
@ -169,25 +193,23 @@ public class InternalReport {
break;
}
}
if (!found) {
InternalReport rptLine = new InternalReport(
InternalType.EXTRA, s);
reports.add(rptLine);
}
}
InternalReport rptLine = new InternalReport(InternalType.END, "");
reports.add(rptLine);
}
return reports;
}
/**
* Separate Lines.
*
* @param message
* @return
* @return reportLines
*/
private static List<String> separateLines(byte[] message) {
List<String> reportLines = null;

View file

@ -18,8 +18,9 @@
* further licensing information.
**/
package com.raytheon.uf.edex.plugin.svrwx.decoder;
/**
* TODO Add Description
* Internal Line Type.
*
* <pre>
*
@ -28,6 +29,7 @@ package com.raytheon.uf.edex.plugin.svrwx.decoder;
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Jan 05, 2010 jsanchez Initial creation
* Apr 10, 2014 skorolev Cleaned code.
*
* </pre>
*
@ -35,10 +37,5 @@ package com.raytheon.uf.edex.plugin.svrwx.decoder;
* @version 1.0
*/
public enum InternalType {
TIME_RANGE,
REPORT_TYPE,
EVENT_LN,
REMARKS,
EXTRA,
END;
TIME_RANGE, REPORT_TYPE, EVENT_LN, REMARKS, EXTRA, END, WRONG_LN;
}

View file

@ -29,9 +29,6 @@ import java.util.TimeZone;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.raytheon.edex.esb.Headers;
import com.raytheon.uf.common.dataplugin.PluginException;
import com.raytheon.uf.common.dataplugin.svrwx.SvrWxRecord;
@ -39,12 +36,14 @@ import com.raytheon.uf.common.pointdata.PointDataContainer;
import com.raytheon.uf.common.pointdata.PointDataDescription;
import com.raytheon.uf.common.pointdata.PointDataView;
import com.raytheon.uf.common.pointdata.spatial.SurfaceObsLocation;
import com.raytheon.uf.common.status.IUFStatusHandler;
import com.raytheon.uf.common.status.UFStatus;
import com.raytheon.uf.common.time.DataTime;
import com.raytheon.uf.edex.plugin.svrwx.SvrWxRecordDao;
import com.raytheon.uf.edex.wmo.message.WMOHeader;
/**
*
* SvrWx Parser
*
* <pre>
*
@ -53,6 +52,7 @@ import com.raytheon.uf.edex.wmo.message.WMOHeader;
* ------------ ---------- ----------- --------------------------
* Jan 04, 2010 jsanchez Initial creation
* Aug 30, 2013 2298 rjpeter Make getPluginName abstract
* Apr 07, 2014 2971 skorolev Add condition to avoid malformed parts in the message.
*
* </pre>
*
@ -62,7 +62,8 @@ import com.raytheon.uf.edex.wmo.message.WMOHeader;
public class SvrWxParser {
/** The logger */
private final Log logger = LogFactory.getLog(getClass());
private static IUFStatusHandler logger = UFStatus
.getHandler(SvrWxParser.class);
private final PointDataDescription pointDataDescription;
@ -108,6 +109,26 @@ public class SvrWxParser {
private static final HashMap<String, Integer> MONTH_MAP = new HashMap<String, Integer>();
/** List of lines with non-parsed location. */
private List<String> badLines;
private static final Pattern EVENT_KEY_PTRN = Pattern
.compile(InternalReport.EVENT_KEY);
private static final Pattern DATE_TIME_PTRN = Pattern
.compile(InternalReport.TIME);
private static final Pattern LAT_LON_PTRN = Pattern
.compile(InternalReport.LATLON);
private static final Pattern STATION_ID_PTRN = Pattern
.compile(InternalReport.STATIONID);
private static final Pattern yearPtrn = Pattern.compile("\\d{4,4}");
private static final Pattern monthPtrn = Pattern
.compile("(JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC)");
static {
MONTH_MAP.put("JAN", 1);
MONTH_MAP.put("FEB", 2);
@ -124,10 +145,11 @@ public class SvrWxParser {
}
/**
* SvrWx Parser.
*
* @param message
* @param wmoHeader
* @param dao
* @param pdd
* @param name
*/
public SvrWxParser(SvrWxRecordDao dao, PointDataDescription pdd, String name) {
pointDataDescription = pdd;
@ -143,13 +165,26 @@ public class SvrWxParser {
* Raw message data.
* @param traceId
* Trace id for this data.
* @param headers
*/
public void setData(byte[] message, String traceId, Headers headers) {
currentReport = -1;
badLines = new ArrayList<String>();
this.traceId = traceId;
wmoHeader = new WMOHeader(message, headers);
if (wmoHeader != null) {
reports = findReports(message);
if (!badLines.isEmpty()) {
StringBuilder warnMsg = new StringBuilder("Message ");
warnMsg.append(wmoHeader);
warnMsg.append(" skipped lines:");
for (String s : badLines) {
warnMsg.append("\nUnrecognized location: ");
warnMsg.append(s);
}
logger.warn(warnMsg.toString());
badLines.clear();
}
} else {
logger.error(traceId + "- Missing or invalid WMOHeader");
}
@ -193,7 +228,6 @@ public class SvrWxParser {
} else {
report = reports.get(currentReport++);
logger.debug("Getting report " + report);
try {
report.constructDataURI();
if (URI_MAP.containsKey(report.getDataURI())) {
@ -227,6 +261,7 @@ public class SvrWxParser {
}
/**
* Gets Container
*
* @param obsData
* @return
@ -243,9 +278,10 @@ public class SvrWxParser {
}
/**
* Collect Reports from svrWx Records.
*
* @param start
* @return
* @param message
* @return reports
*/
private List<SvrWxRecord> findReports(byte[] message) {
@ -261,7 +297,8 @@ public class SvrWxParser {
parseTimeRangeLine(rpt.getReportLine());
break;
case REPORT_TYPE:
if ((reportType != null) && (eventKey != null)) {
if ((reportType != null && eventKey != null)
&& isStationOk()) {
SurfaceObsLocation location = new SurfaceObsLocation(
stationId);
location.setLongitude(longitude.doubleValue());
@ -278,7 +315,8 @@ public class SvrWxParser {
clearData();
break;
case EVENT_LN:
if ((reportType != null) && (eventKey != null)) {
if ((reportType != null && eventKey != null)
&& isStationOk()) {
SurfaceObsLocation location = new SurfaceObsLocation(
stationId);
location.setLongitude(longitude.doubleValue());
@ -303,9 +341,13 @@ public class SvrWxParser {
if ((s.length() != 0) && (remarks != null)) {
remarks += " " + s;
}
if (s.length() != 0 && eventKey != null && !isStationOk()) {
badLines.add(s);
}
break;
case END:
if ((reportType != null) && (eventKey != null)) {
if ((reportType != null && eventKey != null)
&& isStationOk()) {
SurfaceObsLocation location = new SurfaceObsLocation(
stationId);
location.setLongitude(longitude.doubleValue());
@ -327,26 +369,29 @@ public class SvrWxParser {
return reports;
}
/**
* Parse Time Range Line.
*
* @param timeRangeLine
*/
private void parseTimeRangeLine(String timeRangeLine) {
Pattern yearPtrn = Pattern.compile("\\d{4,4}");
Pattern monthPtrn = Pattern
.compile("(JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC)");
Matcher m = monthPtrn.matcher(timeRangeLine);
if (m.find()) {
month = MONTH_MAP.get(m.group());
}
m = yearPtrn.matcher(timeRangeLine);
if (m.find()) {
year = Integer.parseInt(m.group());
}
}
/**
* Parse Event Key Line.
*
* @param eventKeyLine
*/
private void parseEventKeyLine(String eventKeyLine) {
Pattern eventKeyPtrn = Pattern.compile(InternalReport.EVENT_KEY);
Pattern dateTimePtrn = Pattern.compile(InternalReport.TIME);
Matcher m = eventKeyPtrn.matcher(eventKeyLine);
Matcher m = EVENT_KEY_PTRN.matcher(eventKeyLine);
if (m.find()) {
String type = m.group();
if (type.equals(TORN)) {
@ -360,10 +405,9 @@ public class SvrWxParser {
eventKey = type.replace(" ", "");
reportType = "A";
}
}
m = dateTimePtrn.matcher(eventKeyLine);
m = DATE_TIME_PTRN.matcher(eventKeyLine);
if (m.find()) {
String time = m.group();
greenTime = time.replace("/", ".");
@ -383,18 +427,19 @@ public class SvrWxParser {
cal.set(Calendar.MILLISECOND, 0);
cal.setTimeZone(TimeZone.getTimeZone("GMT"));
refTime = new DataTime(cal);
} else {
refTime = null;
}
}
/**
* Parse Remarks Line.
*
* @param remarksLine
*/
private void parseRemarksLine(String remarksLine) {
Pattern latLonPtrn = Pattern.compile(InternalReport.LATLON);
Pattern stationIdPtrn = Pattern.compile(InternalReport.STATIONID);
Matcher m = latLonPtrn.matcher(remarksLine);
Matcher m = LAT_LON_PTRN.matcher(remarksLine);
if (m.find()) {
String latLon = m.group();
String latStr = latLon.substring(0, 4);
@ -403,7 +448,7 @@ public class SvrWxParser {
longitude = Float.parseFloat(lonStr) / -100;
}
m = stationIdPtrn.matcher(remarksLine);
m = STATION_ID_PTRN.matcher(remarksLine);
if (m.find()) {
stationId = m.group();
}
@ -414,6 +459,9 @@ public class SvrWxParser {
}
}
/**
* Clear SvrWx Record.
*/
private void clearData() {
eventKey = null;
refTime = null;
@ -424,6 +472,11 @@ public class SvrWxParser {
greenTime = null;
}
/**
* Get details of SvrWx Record.
*
* @return details
*/
private String getDetails() {
String details = eventKey + " " + greenTime + ":";
if (stationId != null) {
@ -432,4 +485,15 @@ public class SvrWxParser {
details += " " + remarks;
return details;
}
/**
* Checks if parsed location is valid. If it returns false it indicates the
* station or latitude/longitude was not parsed from the product since it
* didn't match.
*
* @return true if location is valid.
*/
private boolean isStationOk() {
return longitude != null && latitude != null && stationId != null;
}
}