Issue #1837: Provide better error logging when a map referenced in localMaps.py cannot be found in the database.

Change-Id: I2400f46f8010ff312c0943b3d08c89d6ce34c5e0

Former-commit-id: 8b98836e103e082ccf266e1030b5fd3351095618
This commit is contained in:
David Gillingham 2013-03-28 11:39:13 -05:00
parent 214b2ed4ba
commit 8a7c965eaa
5 changed files with 168 additions and 30 deletions

View file

@ -30,6 +30,8 @@ import com.raytheon.uf.common.dataplugin.gfe.exception.GfeException;
* Date Ticket# Engineer Description * Date Ticket# Engineer Description
* ------------ ---------- ----------- -------------------------- * ------------ ---------- ----------- --------------------------
* 04/08/08 #875 bphillip Initial Creation * 04/08/08 #875 bphillip Initial Creation
* 03/28/13 #1837 dgilling Implement missing constructors from
* super-class.
* *
* </pre> * </pre>
* *
@ -40,6 +42,10 @@ public class GfeConfigurationException extends GfeException {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
public GfeConfigurationException() {
super();
}
/** /**
* @param aCause * @param aCause
*/ */
@ -58,4 +64,7 @@ public class GfeConfigurationException extends GfeException {
super(aCause, anException); super(aCause, anException);
} }
public GfeConfigurationException(Throwable anException) {
super(anException);
}
} }

View file

@ -0,0 +1,59 @@
/**
* 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.exception;
/**
* Exception thrown when a database table referenced in localMaps.py cannot be
* located in the maps database.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Mar 28, 2013 dgilling Initial creation
*
* </pre>
*
* @author dgilling
* @version 1.0
*/
public class MissingLocalMapsException extends GfeConfigurationException {
private static final long serialVersionUID = 1L;
public MissingLocalMapsException() {
super();
}
public MissingLocalMapsException(String message) {
super(message);
}
public MissingLocalMapsException(String message, Throwable cause) {
super(message, cause);
}
public MissingLocalMapsException(Throwable cause) {
super(cause);
}
}

View file

@ -46,10 +46,10 @@ import org.opengis.filter.Filter;
import org.opengis.filter.FilterFactory2; import org.opengis.filter.FilterFactory2;
import org.opengis.geometry.BoundingBox; import org.opengis.geometry.BoundingBox;
import com.raytheon.edex.plugin.gfe.exception.MissingLocalMapsException;
import com.raytheon.uf.common.dataquery.db.QueryResult; import com.raytheon.uf.common.dataquery.db.QueryResult;
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.edex.core.EDEXUtil; import com.raytheon.uf.edex.core.EDEXUtil;
import com.raytheon.uf.edex.database.tasks.SqlQueryTask; import com.raytheon.uf.edex.database.tasks.SqlQueryTask;
import com.vividsolutions.jts.geom.Geometry; import com.vividsolutions.jts.geom.Geometry;
@ -68,6 +68,8 @@ import com.vividsolutions.jts.geom.Polygon;
* Date Ticket# Engineer Description * Date Ticket# Engineer Description
* ------------ ---------- ----------- -------------------------- * ------------ ---------- ----------- --------------------------
* Sep 18, 2012 #1091 randerso Initial creation * Sep 18, 2012 #1091 randerso Initial creation
* Mar 28, 2013 #1837 dgilling Change error handling in
* getLastUpdated().
* *
* </pre> * </pre>
* *
@ -172,11 +174,16 @@ public class DbShapeSource {
/** /**
* @throws IOException * @throws IOException
* @throws MissingLocalMapsException
* *
*/ */
public void open() throws IOException { public void open() throws IOException, MissingLocalMapsException {
DataStore dataStore = getDataStore(); DataStore dataStore = getDataStore();
try {
schema = dataStore.getSchema(this.tableName); schema = dataStore.getSchema(this.tableName);
} catch (IOException e) {
throw new MissingLocalMapsException(e);
}
shapeField = schema.getGeometryDescriptor().getLocalName(); shapeField = schema.getGeometryDescriptor().getLocalName();
featureCollection = null; featureCollection = null;
@ -247,7 +254,8 @@ public class DbShapeSource {
return featureIterator.next(); return featureIterator.next();
} }
public synchronized ShapeType getShapeType() throws IOException { public synchronized ShapeType getShapeType() throws IOException,
MissingLocalMapsException {
if (this.type == null) { if (this.type == null) {
boolean closeIt = false; boolean closeIt = false;
if (schema == null) { if (schema == null) {
@ -418,6 +426,9 @@ public class DbShapeSource {
} catch (IOException e) { } catch (IOException e) {
statusHandler.error( statusHandler.error(
"IOException reading " + dbShape.getTableName(), e); "IOException reading " + dbShape.getTableName(), e);
} catch (MissingLocalMapsException e) {
statusHandler.error("Could not locate " + dbShape.getTableName()
+ " in the maps database.", e);
} finally { } finally {
try { try {
if (dbShape != null) { if (dbShape != null) {
@ -431,18 +442,17 @@ public class DbShapeSource {
System.out.println("Took " + (System.currentTimeMillis() - t0) + " ms"); System.out.println("Took " + (System.currentTimeMillis() - t0) + " ms");
} }
public Date getLastUpdated() { public Date getLastUpdated() throws MissingLocalMapsException {
Date retVal = new Date();
String sqlQuery = "SELECT import_time FROM " + SCHEMA_NAME String sqlQuery = "SELECT import_time FROM " + SCHEMA_NAME
+ ".map_version WHERE table_name = '" + this.tableName + "';"; + ".map_version WHERE table_name = '" + this.tableName + "';";
try { try {
SqlQueryTask task = new SqlQueryTask(sqlQuery, DB_NAME); SqlQueryTask task = new SqlQueryTask(sqlQuery, DB_NAME);
QueryResult result = task.execute(); QueryResult result = task.execute();
retVal = (Date) result.getRowColumnValue(0, 0); return (Date) result.getRowColumnValue(0, 0);
} catch (Exception e) { } catch (Exception e) {
statusHandler.handle(Priority.PROBLEM, e.getLocalizedMessage(), e); // statusHandler.handle(Priority.PROBLEM, e.getLocalizedMessage(),
// e);
throw new MissingLocalMapsException(e);
} }
return retVal;
} }
} }

View file

@ -47,6 +47,7 @@ import org.opengis.metadata.spatial.PixelOrientation;
import org.opengis.referencing.operation.MathTransform; import org.opengis.referencing.operation.MathTransform;
import com.raytheon.edex.plugin.gfe.config.IFPServerConfig; import com.raytheon.edex.plugin.gfe.config.IFPServerConfig;
import com.raytheon.edex.plugin.gfe.exception.MissingLocalMapsException;
import com.raytheon.edex.plugin.gfe.reference.DbShapeSource.ShapeType; import com.raytheon.edex.plugin.gfe.reference.DbShapeSource.ShapeType;
import com.raytheon.edex.plugin.gfe.textproducts.AreaDictionaryMaker; import com.raytheon.edex.plugin.gfe.textproducts.AreaDictionaryMaker;
import com.raytheon.edex.plugin.gfe.textproducts.CombinationsFileMaker; import com.raytheon.edex.plugin.gfe.textproducts.CombinationsFileMaker;
@ -73,6 +74,7 @@ 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.util.FileUtil; import com.raytheon.uf.common.util.FileUtil;
import com.raytheon.uf.edex.core.EDEXUtil;
import com.vividsolutions.jts.geom.Coordinate; import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.Geometry; import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.GeometryFactory; import com.vividsolutions.jts.geom.GeometryFactory;
@ -96,6 +98,9 @@ import com.vividsolutions.jts.simplify.TopologyPreservingSimplifier;
* Jun 25, 2008 #1210 randerso Modified to get directories from UtilityContext * Jun 25, 2008 #1210 randerso Modified to get directories from UtilityContext
* Oct 13, 2008 #1607 njensen Added genCombinationsFiles() * Oct 13, 2008 #1607 njensen Added genCombinationsFiles()
* Sep 18, 2012 #1091 randerso Changed to use Maps.py and localMaps.py * Sep 18, 2012 #1091 randerso Changed to use Maps.py and localMaps.py
* Mar 28, 2013 #1837 dgilling Better error reporting if a map table
* from localMaps.py could not be found,
* warnings clean up.
* *
* </pre> * </pre>
* *
@ -243,28 +248,21 @@ public class MapManager {
/** /**
* @param maps * @param maps
*/ */
@SuppressWarnings("unused")
/**
* Searches the parent directory of a provided list of shape files to
* determine whether or not they contain a file that is newer than any files
* in a specified directory.
*
* @param maps
* An array of shape files.
* @param directory
* A directory containing the resultant edit areas from the shape
* files.
* @return True, if any file in the parent folder of any of the shape files
* is newer than anything in the specified directory. Else, false.
*/
private boolean updateNeeded(List<DbShapeSource> maps, private boolean updateNeeded(List<DbShapeSource> maps,
final String directory) { final String directory) {
// calc newest file inside maps.directory() // calc newest file inside maps.directory()
long newestSource = Long.MIN_VALUE; long newestSource = Long.MIN_VALUE;
List<DbShapeSource> failedMaps = new ArrayList<DbShapeSource>();
for (DbShapeSource map : maps) { for (DbShapeSource map : maps) {
try {
newestSource = Math.max(newestSource, map.getLastUpdated() newestSource = Math.max(newestSource, map.getLastUpdated()
.getTime()); .getTime());
} catch (MissingLocalMapsException e) {
reportMissingLocalMap(map, "retrieving last update time", e);
failedMaps.add(map);
} }
}
maps.removeAll(failedMaps);
// Determine time of last modification of Maps.py, serverConfig, // Determine time of last modification of Maps.py, serverConfig,
// localConfig, localMaps, and siteConfig. // localConfig, localMaps, and siteConfig.
@ -388,6 +386,10 @@ public class MapManager {
} }
makeReferenceData(m); makeReferenceData(m);
} catch (MissingLocalMapsException e) {
String error = reportMissingLocalMap(m, "retrieving map data",
e);
_mapErrors.add(error);
} catch (Exception e) { } catch (Exception e) {
String error = "********* EDIT AREA GENERATION ERROR - MakeReferenceData *********\n" String error = "********* EDIT AREA GENERATION ERROR - MakeReferenceData *********\n"
+ "Error in generating edit areas, map #" + "Error in generating edit areas, map #"
@ -578,8 +580,8 @@ public class MapManager {
// old one, write a warning to the log. // old one, write a warning to the log.
ReferenceData other = null; ReferenceData other = null;
try { try {
other = (ReferenceData) SerializationUtil other = SerializationUtil.jaxbUnmarshalFromXmlFile(
.jaxbUnmarshalFromXmlFile(path); ReferenceData.class, path);
} catch (Exception e) { } catch (Exception e) {
statusHandler.error("Error reading edit area file " statusHandler.error("Error reading edit area file "
+ path.getAbsolutePath(), e); + path.getAbsolutePath(), e);
@ -965,4 +967,23 @@ public class MapManager {
return s; return s;
} }
private String reportMissingLocalMap(DbShapeSource missingMap,
String operation, MissingLocalMapsException e) {
String errorLog = "Error in " + operation + " for map named ["
+ missingMap.getDisplayName() + "]: Could not find table ["
+ missingMap.getTableName() + "] in maps database.";
statusHandler.error(errorLog, e);
String errorUser = errorLog
+ " Edit areas for this map will not be generated."
+ " Check site ["
+ _config.getSiteID().get(0)
+ "] localMaps.py configuration and verify all necessary shape files have been imported.";
EDEXUtil.sendMessageAlertViz(Priority.ERROR,
"com.raytheon.edex.plugin.gfe", "GFE", "GFE", errorUser,
errorUser, null);
return errorLog;
}
} }

View file

@ -20,7 +20,6 @@
package com.raytheon.uf.common.dataplugin.gfe.exception; package com.raytheon.uf.common.dataplugin.gfe.exception;
/** /**
* Base GFE Exception class * Base GFE Exception class
* *
@ -29,6 +28,8 @@ package com.raytheon.uf.common.dataplugin.gfe.exception;
* Date Ticket# Engineer Description * Date Ticket# Engineer Description
* ------------ ---------- ----------- -------------------------- * ------------ ---------- ----------- --------------------------
* 04/08/08 #875 bphillip Initial Creation * 04/08/08 #875 bphillip Initial Creation
* 03/28/13 #1837 dgilling Implement missing constructors from
* super-class.
* *
* </pre> * </pre>
* *
@ -40,7 +41,22 @@ public class GfeException extends Exception {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
/** /**
* @param aCause * Constructs a new runtime exception with <code>null</code> as its detail
* message. The cause is not initialized, and may subsequently be
* initialized by a call to {@link #initCause}.
*/
public GfeException() {
super();
}
/**
* Constructs a new exception with the specified detail message. The cause
* is not initialized, and may subsequently be initialized by a call to
* {@link #initCause}.
*
* @param message
* the detail message. The detail message is saved for later
* retrieval by the {@link #getMessage()} method.
*/ */
public GfeException(String aCause) { public GfeException(String aCause) {
super(aCause); super(aCause);
@ -51,9 +67,32 @@ public class GfeException extends Exception {
* exception chaining to preserve state. * exception chaining to preserve state.
* *
* @param aCause * @param aCause
* the detail message (which is saved for later retrieval by the
* {@link #getMessage()} method).
* @param anException * @param anException
* the cause (which is saved for later retrieval by the
* {@link #getCause()} method). (A <tt>null</tt> value is
* permitted, and indicates that the cause is nonexistent or
* unknown.)
*/ */
public GfeException(String aCause, Throwable anException) { public GfeException(String aCause, Throwable anException) {
super(aCause, anException); super(aCause, anException);
} }
/**
* Constructs a new exception with the specified cause and a detail message
* of <tt>(cause==null ? null : cause.toString())</tt> (which typically
* contains the class and detail message of <tt>cause</tt>). This
* constructor is useful for exceptions that are little more than wrappers
* for other throwables.
*
* @param cause
* the cause (which is saved for later retrieval by the
* {@link #getCause()} method). (A <tt>null</tt> value is
* permitted, and indicates that the cause is nonexistent or
* unknown.)
*/
public GfeException(Throwable anException) {
super(anException);
}
} }