ASM #94
Change-Id: I97797a7adbd17532b261987caf2fdcaa1d39c9ed Former-commit-id:42399284ca
[formerly42399284ca
[formerly 3c9c34c84ac1cd4962c3e6f877bd33b37aab705a]] Former-commit-id:b63053d8b4
Former-commit-id:60de3bbc43
This commit is contained in:
parent
fb6f16fcb5
commit
e5ca7e8740
7 changed files with 273 additions and 17 deletions
|
@ -94,6 +94,10 @@ import com.raytheon.uf.viz.core.exception.VizException;
|
|||
import com.raytheon.uf.viz.core.localization.LocalizationManager;
|
||||
import com.raytheon.uf.viz.core.map.MapDescriptor;
|
||||
import com.raytheon.uf.viz.core.maps.MapManager;
|
||||
import com.raytheon.uf.viz.core.notification.INotificationObserver;
|
||||
import com.raytheon.uf.viz.core.notification.NotificationException;
|
||||
import com.raytheon.uf.viz.core.notification.NotificationMessage;
|
||||
import com.raytheon.uf.viz.core.notification.jobs.NotificationManagerJob;
|
||||
import com.raytheon.uf.viz.core.rsc.LoadProperties;
|
||||
import com.raytheon.uf.viz.core.rsc.ResourceProperties;
|
||||
import com.raytheon.uf.viz.core.rsc.capabilities.ColorableCapability;
|
||||
|
@ -196,6 +200,8 @@ import com.vividsolutions.jts.io.WKTReader;
|
|||
* 10/29/2013 DR 16734 D. Friedman If redraw-from-hatched-area fails, don't allow the pollygon the be used.
|
||||
* 12/17/2013 DR 16567 Qinglu Lin Added findLargestGeometry() and findLargestQuadrant(), and updated
|
||||
* populateStrings() and paintText().
|
||||
* 02/07/2014 DR16090 m.gamazaychikov Added GeomMetaDataUpdateNotificationObserver class to get notification
|
||||
* when geometry file get updated to re-read them in.
|
||||
* </pre>
|
||||
*
|
||||
* @author mschenke
|
||||
|
@ -541,6 +547,56 @@ public class WarngenLayer extends AbstractStormTrackResource {
|
|||
|
||||
}
|
||||
|
||||
private static class GeomMetaDataUpdateNotificationObserver implements INotificationObserver {
|
||||
|
||||
private static final String SHAPEFILE_UPDATE_TOPIC = "edex.geospatialUpdate.msg";
|
||||
|
||||
private static GeomMetaDataUpdateNotificationObserver instance = null;
|
||||
|
||||
static WarngenLayer warngenLayer;
|
||||
|
||||
private GeomMetaDataUpdateNotificationObserver() {
|
||||
}
|
||||
|
||||
public static synchronized GeomMetaDataUpdateNotificationObserver getInstance(WarngenLayer wl) {
|
||||
if (instance == null) {
|
||||
instance = new GeomMetaDataUpdateNotificationObserver();
|
||||
NotificationManagerJob.addObserver(SHAPEFILE_UPDATE_TOPIC, instance);
|
||||
warngenLayer = wl;
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the alert message observer from the Notification Manager Job
|
||||
* listener.
|
||||
*/
|
||||
public static synchronized void removeNotificationObserver() {
|
||||
if (instance != null) {
|
||||
NotificationManagerJob.removeObserver(SHAPEFILE_UPDATE_TOPIC, instance);
|
||||
instance = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notificationArrived(NotificationMessage[] messages) {
|
||||
for (NotificationMessage message : messages) {
|
||||
try {
|
||||
Object payload = message.getMessagePayload();
|
||||
if (payload instanceof String ) {
|
||||
System.out.println("Geometry Metadata has been updated based on " + payload + " shapefile data");
|
||||
warngenLayer.siteMap.clear();
|
||||
warngenLayer.init(warngenLayer.configuration);
|
||||
}
|
||||
} catch (NotificationException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static Map<String, GeospatialDataList> siteMap = new HashMap<String, GeospatialDataList>();
|
||||
|
||||
private static Map<String, Geometry> timezoneMap = new HashMap<String, Geometry>();
|
||||
|
@ -604,6 +660,8 @@ public class WarngenLayer extends AbstractStormTrackResource {
|
|||
|
||||
private WarningAction warningAction = WarningAction.NEW;
|
||||
|
||||
private GeomMetaDataUpdateNotificationObserver geomUpdateObserver;
|
||||
|
||||
static {
|
||||
for (int i = 0; i < 128; i++) {
|
||||
if (i % 32 == 0) {
|
||||
|
@ -756,6 +814,8 @@ public class WarngenLayer extends AbstractStormTrackResource {
|
|||
protected void disposeInternal() {
|
||||
customMaps.clearMaps();
|
||||
|
||||
GeomMetaDataUpdateNotificationObserver.removeNotificationObserver();
|
||||
|
||||
super.disposeInternal();
|
||||
|
||||
synchronized (WarngenLayer.class) {
|
||||
|
@ -1051,6 +1111,8 @@ public class WarngenLayer extends AbstractStormTrackResource {
|
|||
|
||||
String site = getLocalizedSite();
|
||||
|
||||
initializeGeomUpdateObserver();
|
||||
|
||||
synchronized (siteMap) {
|
||||
loadGeodataForConfiguration(config);
|
||||
|
||||
|
@ -1075,6 +1137,12 @@ public class WarngenLayer extends AbstractStormTrackResource {
|
|||
+ (System.currentTimeMillis() - t0) + "ms");
|
||||
}
|
||||
|
||||
private void initializeGeomUpdateObserver() {
|
||||
if (geomUpdateObserver == null) {
|
||||
geomUpdateObserver= GeomMetaDataUpdateNotificationObserver.getInstance(this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds geospatial data to siteMap and timezoneMap for the given template
|
||||
* configuration. This must not have any site effects on the currently
|
||||
|
|
|
@ -13,6 +13,9 @@ acarssounding.cron=00+10,30,50+*+*+*+?
|
|||
gfe.cron=0+15+*+*+*+?
|
||||
repack.cron=0+20+*+*+*+?
|
||||
|
||||
# warngen geometries updater
|
||||
geospatial.updater.cron=0+0+0/1+*+*+?
|
||||
|
||||
###purge configuration
|
||||
# Interval at which the purge job kicks off
|
||||
purge.cron=0+0/1+*+*+*+?
|
||||
|
|
|
@ -261,6 +261,13 @@
|
|||
<bean ref="serializationUtil" method="transformToThrift" />
|
||||
<to uri="jms-generic:topic:edex.alarms.msg" />
|
||||
</route>
|
||||
|
||||
<!-- Route to send geospatial data update notification -->
|
||||
<route id="geospatialUpdateNotify">
|
||||
<from uri="vm:edex.geospatialUpdateNotification" />
|
||||
<bean ref="serializationUtil" method="transformToThrift" />
|
||||
<to uri="jms-generic:topic:edex.geospatialUpdate.msg" />
|
||||
</route>
|
||||
|
||||
<!-- Route to periodically close any unused jms resources that have been pooled -->
|
||||
<route id="jmsPooledResourceChecker">
|
||||
|
|
|
@ -20,4 +20,5 @@ Require-Bundle: org.geotools,
|
|||
Export-Package: com.raytheon.edex.plugin.warning.tools
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
|
||||
Import-Package: com.raytheon.uf.common.time,
|
||||
org.apache.commons.logging,
|
||||
org.hibernate.annotations
|
||||
|
|
|
@ -11,4 +11,32 @@
|
|||
|
||||
<!-- Instantiating class causes a thread to be run that will generate the warngen geometries -->
|
||||
<bean class="com.raytheon.edex.plugin.warning.gis.GeospatialDataGeneratorThread"/>
|
||||
|
||||
<!--Instantiating class will update the warngen geometries-->
|
||||
<bean id="geospatialDataUpdater" class="com.raytheon.edex.plugin.warning.gis.GeospatialDataUpdater" />
|
||||
|
||||
<camelContext id="geospatialDataUpdater-context"
|
||||
xmlns="http://camel.apache.org/schema/spring" errorHandlerRef="errorHandler">
|
||||
|
||||
<endpoint id="geospatialDataUpdaterCron"
|
||||
uri="clusteredquartz://warning/geospatialDataUpdaterScheduled/?cron=${geospatial.updater.cron}" />
|
||||
|
||||
<route id="geospatialDataUpdaterScheduled">
|
||||
<from uri="geospatialDataUpdaterCron" />
|
||||
<to uri="jms-generic:queue:geospatialDataUpdaterScheduledWork" />
|
||||
</route>
|
||||
|
||||
<route id="geospatialDataUpdaterScheduledWork">
|
||||
<from uri="jms-generic:queue:geospatialDataUpdaterScheduledWork" />
|
||||
<doTry>
|
||||
<bean ref="geospatialDataUpdater" method="runCheckUpdate" />
|
||||
<doCatch>
|
||||
<exception>java.lang.Throwable</exception>
|
||||
<to
|
||||
uri="log:geospatialDataUpdater?level=ERROR" />
|
||||
</doCatch>
|
||||
</doTry>
|
||||
</route>
|
||||
</camelContext>
|
||||
|
||||
</beans>
|
|
@ -96,6 +96,7 @@ import com.vividsolutions.jts.simplify.TopologyPreservingSimplifier;
|
|||
* AreaConfiguration to areaFields List.
|
||||
* May 7, 2013 15690 Qinglu Lin Added convertToMultiPolygon() and updated queryGeospatialData().
|
||||
* Oct 22, 2013 2361 njensen Use JAXBManager for XML
|
||||
* Feb 07, 2014 16090 mgamazaychikov Changed visibility of some methods
|
||||
* </pre>
|
||||
*
|
||||
* @author rjpeter
|
||||
|
@ -124,12 +125,31 @@ public class GeospatialDataGenerator {
|
|||
List<String> sites = getBackupSites(dialogConfig);
|
||||
sites.add(0, mySite);
|
||||
List<String> templates = getTemplates(dialogConfig);
|
||||
Set<GeospatialMetadata> metaDataSet = getMetaDataSet(sites, templates);
|
||||
|
||||
for (String site : sites) {
|
||||
statusHandler.handle(Priority.INFO,
|
||||
"Generating warngen geometries for site: " + site);
|
||||
for (GeospatialMetadata md : metaDataSet) {
|
||||
try {
|
||||
generateGeoSpatialList(site, md);
|
||||
} catch (Exception e) {
|
||||
statusHandler
|
||||
.handle(Priority.ERROR,
|
||||
"Failed to generate geospatial data for warngen",
|
||||
e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static Set<GeospatialMetadata> getMetaDataSet(List<String> sites,
|
||||
List<String> templates) {
|
||||
|
||||
Set<GeospatialMetadata> metaDataSet = new HashSet<GeospatialMetadata>();
|
||||
|
||||
for (String site : sites) {
|
||||
metaDataSet.clear();
|
||||
statusHandler.handle(Priority.INFO,
|
||||
"Generating warngen geometries for site: " + site);
|
||||
|
||||
// get the unique geospatialMetadata sets to generate
|
||||
for (String templateName : templates) {
|
||||
|
@ -155,21 +175,10 @@ public class GeospatialDataGenerator {
|
|||
metaDataSet.add(gmd);
|
||||
}
|
||||
}
|
||||
|
||||
for (GeospatialMetadata md : metaDataSet) {
|
||||
try {
|
||||
generateGeoSpatialList(site, md);
|
||||
} catch (Exception e) {
|
||||
statusHandler
|
||||
.handle(Priority.ERROR,
|
||||
"Failed to generate geospatial data for warngen",
|
||||
e);
|
||||
}
|
||||
}
|
||||
}
|
||||
return metaDataSet;
|
||||
}
|
||||
|
||||
private static List<String> getBackupSites(DialogConfiguration dialogConfig) {
|
||||
static List<String> getBackupSites(DialogConfiguration dialogConfig) {
|
||||
String[] CWAs = dialogConfig.getBackupCWAs().split(",");
|
||||
List<String> rval = new ArrayList<String>(CWAs.length + 1);
|
||||
for (String s : CWAs) {
|
||||
|
@ -180,7 +189,7 @@ public class GeospatialDataGenerator {
|
|||
return rval;
|
||||
}
|
||||
|
||||
private static List<String> getTemplates(DialogConfiguration dialogConfig) {
|
||||
static List<String> getTemplates(DialogConfiguration dialogConfig) {
|
||||
String[] mainProducts = dialogConfig.getMainWarngenProducts()
|
||||
.split(",");
|
||||
String[] otherProducts = dialogConfig.getOtherWarngenProducts().split(
|
||||
|
@ -337,7 +346,7 @@ public class GeospatialDataGenerator {
|
|||
return rval;
|
||||
}
|
||||
|
||||
private static GeospatialTime queryForCurrentTimes(
|
||||
static GeospatialTime queryForCurrentTimes(
|
||||
GeospatialMetadata metaData) throws Exception {
|
||||
GeospatialTime rval = new GeospatialTime();
|
||||
String areaSource = metaData.getAreaSource().toLowerCase();
|
||||
|
|
|
@ -0,0 +1,140 @@
|
|||
package com.raytheon.edex.plugin.warning.gis;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Calendar;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import com.raytheon.edex.site.SiteUtil;
|
||||
import com.raytheon.edex.util.Util;
|
||||
import com.raytheon.uf.common.dataplugin.warning.config.DialogConfiguration;
|
||||
import com.raytheon.uf.common.dataplugin.warning.gis.GeospatialFactory;
|
||||
import com.raytheon.uf.common.dataplugin.warning.gis.GeospatialMetadata;
|
||||
import com.raytheon.uf.common.dataplugin.warning.gis.GeospatialTime;
|
||||
import com.raytheon.uf.common.geospatial.SpatialException;
|
||||
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.edex.core.EDEXUtil;
|
||||
import com.raytheon.uf.edex.core.EdexException;
|
||||
|
||||
/**
|
||||
* Compares current time in the database against the time of last run
|
||||
* generated geometry and if they differ regenerates the files.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Feb 07, 2014 16090 mgamazaychikov Initial creation
|
||||
* </pre>
|
||||
*
|
||||
* @author mgamazaychikov
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class GeospatialDataUpdater {
|
||||
private final static IUFStatusHandler statusHandler = UFStatus
|
||||
.getHandler(GeospatialDataUpdater.class);
|
||||
private static final String UPDATER_ENDPOINT = "geospatialUpdateNotify";
|
||||
private static Log logger = LogFactory.getLog(Util.class);
|
||||
|
||||
private static Set<GeospatialMetadata> metaDataSet = null;
|
||||
private static Map<GeospatialMetadata, GeospatialTime> map = null;
|
||||
|
||||
public static void runCheckUpdate() throws SpatialException {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
if (metaDataSet == null){
|
||||
runInit();
|
||||
}
|
||||
GeospatialTime curTime = null;
|
||||
GeospatialTime lastRunTime = null;
|
||||
boolean generate = false;
|
||||
sb.append("GeospatialDataUpdater: ");
|
||||
for (GeospatialMetadata md : metaDataSet) {
|
||||
lastRunTime = map.get(md);
|
||||
try {
|
||||
curTime = GeospatialDataGenerator.queryForCurrentTimes(md);
|
||||
} catch (Exception e) {
|
||||
throw new SpatialException(
|
||||
"Unable to look up database version times.",
|
||||
e);
|
||||
}
|
||||
if (!curTime.equals(lastRunTime)) {
|
||||
generate = true;
|
||||
break;
|
||||
}
|
||||
else {
|
||||
generate = false;
|
||||
}
|
||||
}
|
||||
if (generate){
|
||||
sb.append("Geometry database time differs from current geometry metadata time: regenerating geometries");
|
||||
}
|
||||
else {
|
||||
return;
|
||||
}
|
||||
if (statusHandler.isPriorityEnabled(Priority.INFO)) {
|
||||
statusHandler.info(sb.toString());
|
||||
}
|
||||
GeospatialDataGenerator.generateUniqueGeospatialMetadataGeometries();
|
||||
|
||||
String updatedTimeStamp = getTimeStamp(curTime, lastRunTime);
|
||||
try {
|
||||
EDEXUtil.getMessageProducer().sendAsync(UPDATER_ENDPOINT, updatedTimeStamp);
|
||||
} catch (EdexException e) {
|
||||
logger.error("Could not send message to alarm/alert", e);
|
||||
}
|
||||
metaDataSet = null;
|
||||
}
|
||||
|
||||
private static String getTimeStamp(GeospatialTime curTime,
|
||||
GeospatialTime lastRunTime) {
|
||||
long tmStampMs = 0;
|
||||
if (curTime.getAreaSourceTime() != lastRunTime.getAreaSourceTime()) {
|
||||
tmStampMs = curTime.getAreaSourceTime();
|
||||
} else if (curTime.getParentSourceTime() != lastRunTime.getParentSourceTime()) {
|
||||
tmStampMs = curTime.getParentSourceTime();
|
||||
} else if (curTime.getTimeZoneSourceTime() != lastRunTime.getTimeZoneSourceTime()) {
|
||||
tmStampMs = curTime.getTimeZoneSourceTime();
|
||||
}
|
||||
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
|
||||
sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.setTimeZone(TimeZone.getTimeZone("GMT"));
|
||||
calendar.setTimeInMillis(tmStampMs);
|
||||
return sdf.format(calendar.getTime());
|
||||
}
|
||||
|
||||
private static void runInit() {
|
||||
String mySite = SiteUtil.getSite();
|
||||
DialogConfiguration dialogConfig = null;
|
||||
|
||||
try {
|
||||
dialogConfig = DialogConfiguration.loadDialogConfig(mySite);
|
||||
} catch (Exception e) {
|
||||
statusHandler.handle(Priority.ERROR,
|
||||
"Error loading warngen config.xml", e);
|
||||
return;
|
||||
}
|
||||
List<String> sites = GeospatialDataGenerator.getBackupSites(dialogConfig);
|
||||
sites.add(0, mySite);
|
||||
List<String> templates = GeospatialDataGenerator.getTemplates(dialogConfig);
|
||||
metaDataSet = GeospatialDataGenerator.getMetaDataSet(sites, templates);
|
||||
map = GeospatialFactory.loadLastRunGeoTimeSet(mySite);
|
||||
StringBuilder sb = new StringBuilder();
|
||||
if (statusHandler.isPriorityEnabled(Priority.INFO)) {
|
||||
sb.append("GeospatialDataUpdater has been re-inited");
|
||||
statusHandler.info(sb.toString());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Loading…
Add table
Reference in a new issue