Merge branch 'master_14.2.1' into master_14.2.2
Former-commit-id:a7c9ddc05e
[formerly2a4fe3dbae
[formerly 64ca88d2ed7de18f9ed1f57edd2286bbc552135f]] Former-commit-id:2a4fe3dbae
Former-commit-id:88d44a3129
This commit is contained in:
commit
4938304674
22 changed files with 688 additions and 433 deletions
|
@ -44,7 +44,10 @@ import com.raytheon.uf.viz.core.exception.VizException;
|
|||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Dec 16, 2011 mschenke Initial creation
|
||||
* Dec 16, 2011 mschenke Initial creation
|
||||
* Feb 27, 2013 #1532 bsteffen Delete uf.common.colormap.image
|
||||
* Nov 11, 2013 #2492 mschenke Added getDataUnti to IColormappedImage
|
||||
* Apr 15, 2014 #3016 randerso Fix null pointer during construction
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -107,7 +110,9 @@ public class ColormappedImage implements IColormappedImage,
|
|||
*/
|
||||
@Override
|
||||
public void dispose() {
|
||||
image.dispose();
|
||||
if (image != null) {
|
||||
image.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -25,6 +25,7 @@ import java.util.HashSet;
|
|||
import java.util.Set;
|
||||
|
||||
import org.eclipse.core.runtime.FileLocator;
|
||||
import org.eclipse.osgi.framework.internal.core.BundleRepository;
|
||||
import org.osgi.framework.Bundle;
|
||||
import org.osgi.framework.wiring.BundleWiring;
|
||||
import org.reflections.Reflections;
|
||||
|
@ -47,6 +48,7 @@ import org.reflections.util.ConfigurationBuilder;
|
|||
* ------------- -------- ----------- --------------------------
|
||||
* Oct 21, 2013 2491 bsteffen Initial creation
|
||||
* Jan 22, 2014 2062 bsteffen Handle bundles with no wiring.
|
||||
* Apr 16, 2014 3018 njensen Synchronize against BundleRepository
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -58,11 +60,26 @@ public class BundleReflections {
|
|||
|
||||
private final Reflections reflections;
|
||||
|
||||
@SuppressWarnings("restriction")
|
||||
public BundleReflections(Bundle bundle, Scanner scanner) throws IOException {
|
||||
ConfigurationBuilder cb = new ConfigurationBuilder();
|
||||
BundleWiring bundleWiring = bundle.adapt(BundleWiring.class);
|
||||
BundleRepository bundleRepo = BundleRepositoryGetter
|
||||
.getFrameworkBundleRepository(bundle);
|
||||
|
||||
if (bundleWiring != null) {
|
||||
cb.addClassLoader(bundleWiring.getClassLoader());
|
||||
if (bundleRepo != null) {
|
||||
synchronized (bundleRepo) {
|
||||
cb.addClassLoader(bundleWiring.getClassLoader());
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* even if we couldn't get the bundle repository to sync
|
||||
* against, it's probably safe, see BundleRepositoryGetter
|
||||
* javadoc
|
||||
*/
|
||||
cb.addClassLoader(bundleWiring.getClassLoader());
|
||||
}
|
||||
cb.addUrls(FileLocator.getBundleFile(bundle).toURI().toURL());
|
||||
cb.setScanners(scanner);
|
||||
reflections = cb.build();
|
||||
|
@ -87,4 +104,5 @@ public class BundleReflections {
|
|||
}
|
||||
return subTypes;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,104 @@
|
|||
/**
|
||||
* 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.viz.core.reflect;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import org.eclipse.osgi.framework.internal.core.AbstractBundle;
|
||||
import org.eclipse.osgi.framework.internal.core.BundleRepository;
|
||||
import org.eclipse.osgi.framework.internal.core.Framework;
|
||||
import org.osgi.framework.Bundle;
|
||||
|
||||
/**
|
||||
* Utility class to get the BundleRepository object associated with a Bundle, to
|
||||
* potentially synchronize against that object.
|
||||
*
|
||||
* Specifically if a call to BundleWiring.getClassLoader() is invoked on a
|
||||
* thread other than main/UI thread, then there is a possible deadlock if the
|
||||
* application shuts down while the BundleWiring.getClassLoader() call is still
|
||||
* going. The BundleRepository of the Framework is the primary resource that is
|
||||
* in contention in this deadlock scenario, due to the BundleRepository being
|
||||
* used as a synchronization lock both deep in bundleWiring.getClassloader() and
|
||||
* in Framework shutdown code. The other resource used as a synchronization lock
|
||||
* and causing the deadlock is the BundleLoader associated with the bundle.
|
||||
*
|
||||
* Therefore to avoid this deadlock, if you are going to call
|
||||
* BundleWiring.getClassLoader() you should attempt to get the BundleRepository
|
||||
* and synchronize against it. This will ensure the call to getClassLoader() can
|
||||
* finish and then release synchronization locks of both the BundleRepository
|
||||
* and BundleLoader.
|
||||
*
|
||||
* If we fail to get the BundleRepository due to access restrictions, then you
|
||||
* should proceed onwards anyway because the odds of the application shutting
|
||||
* down at the same time as the call to BundleWiring.getClassLoader() is still
|
||||
* running is low. Even if that occurs, the odds are further reduced that the
|
||||
* two threads will synchronize against the BundleRepository at the same time
|
||||
* and deadlock.
|
||||
*
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Apr 17, 2014 njensen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author njensen
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class BundleRepositoryGetter {
|
||||
|
||||
private BundleRepositoryGetter() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to retrieve the BundleRepository associated with the bundle's
|
||||
* framework. Returns the BundleRepository or null if it could not be
|
||||
* retrieved.
|
||||
*
|
||||
* @param bundle
|
||||
* the bundle to retrieve the associated BundleRepository for
|
||||
* @return the BundleRepository or null
|
||||
*/
|
||||
@SuppressWarnings("restriction")
|
||||
protected static BundleRepository getFrameworkBundleRepository(Bundle bundle) {
|
||||
BundleRepository bundleRepo = null;
|
||||
if (bundle instanceof AbstractBundle) {
|
||||
try {
|
||||
AbstractBundle ab = (AbstractBundle) bundle;
|
||||
Field bundleRepoField = Framework.getField(Framework.class,
|
||||
BundleRepository.class, true);
|
||||
bundleRepo = (BundleRepository) bundleRepoField.get(ab
|
||||
.getFramework());
|
||||
} catch (Throwable t) {
|
||||
// intentionally log to console and proceed anyway
|
||||
t.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
return bundleRepo;
|
||||
}
|
||||
|
||||
}
|
|
@ -28,6 +28,7 @@ import java.util.HashSet;
|
|||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.eclipse.osgi.framework.internal.core.BundleRepository;
|
||||
import org.osgi.framework.Bundle;
|
||||
import org.osgi.framework.namespace.BundleNamespace;
|
||||
import org.osgi.framework.namespace.PackageNamespace;
|
||||
|
@ -56,6 +57,7 @@ import com.raytheon.uf.viz.core.Activator;
|
|||
* Dec 10, 2013 2602 bsteffen Add null checks to detect unloaded
|
||||
* bundles.
|
||||
* Feb 03, 2013 2764 bsteffen Use OSGi API to get dependencies.
|
||||
* Apr 17, 2014 3018 njensen Synchronize against BundleRepository
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -95,6 +97,7 @@ public class SubClassLocator implements ISubClassLocator {
|
|||
* @param base
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public Collection<Class<?>> locateSubClasses(Class<?> base) {
|
||||
Map<String, Set<Class<?>>> recursiveClasses = new HashMap<String, Set<Class<?>>>(
|
||||
bundleLookup.size(), 1.0f);
|
||||
|
@ -109,6 +112,7 @@ public class SubClassLocator implements ISubClassLocator {
|
|||
/**
|
||||
* Store the cache to disk.
|
||||
*/
|
||||
@Override
|
||||
public void save() {
|
||||
cache.save();
|
||||
}
|
||||
|
@ -265,10 +269,25 @@ public class SubClassLocator implements ISubClassLocator {
|
|||
if (bundleWiring == null) {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
ClassLoader loader = bundleWiring.getClassLoader();
|
||||
|
||||
BundleRepository bundleRepo = BundleRepositoryGetter
|
||||
.getFrameworkBundleRepository(bundle);
|
||||
ClassLoader loader = null;
|
||||
if (bundleRepo != null) {
|
||||
synchronized (bundleRepo) {
|
||||
loader = bundleWiring.getClassLoader();
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* even if we couldn't get the bundle repository to sync against,
|
||||
* it's probably safe, see BundleRepositoryGetter javadoc
|
||||
*/
|
||||
loader = bundleWiring.getClassLoader();
|
||||
}
|
||||
if (loader == null) {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
HashSet<Class<?>> result = new HashSet<Class<?>>(classNames.size(),
|
||||
1.0f);
|
||||
for (String className : classNames) {
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
from com.raytheon.uf.viz.core import GraphicsFactory
|
||||
from com.raytheon.uf.viz.core.drawables import PaintProperties
|
||||
from com.raytheon.viz.core.gl import GLTargetProxy
|
||||
from com.raytheon.uf.viz.core.rsc import ResourceProperties
|
||||
|
||||
#
|
||||
# Base class for Viz painting from python
|
||||
|
@ -32,6 +33,7 @@ from com.raytheon.viz.core.gl import GLTargetProxy
|
|||
# ------------ ---------- ----------- --------------------------
|
||||
# 04/01/09 njensen Initial Creation.
|
||||
# 08/20/2012 #1077 randerso Fixed backgroundColor setting
|
||||
# Apr 16, 2014 3039 njensen Ensure correct ResourceList.add() is used
|
||||
#
|
||||
#
|
||||
#
|
||||
|
@ -83,7 +85,7 @@ class VizPainter():
|
|||
desc = self.getDescriptor()
|
||||
vizResource.setDescriptor(desc)
|
||||
vizResource.init(self.target)
|
||||
desc.getResourceList().add(vizResource)
|
||||
desc.getResourceList().add(vizResource, ResourceProperties())
|
||||
|
||||
def paint(self, time, canvas=None):
|
||||
if type(time) is str:
|
||||
|
@ -130,4 +132,4 @@ class VizPainter():
|
|||
if index > -1:
|
||||
self.getDescriptor().setFrame(index)
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -86,6 +86,7 @@ from com.raytheon.uf.edex.database.cluster import ClusterTask
|
|||
# Changed WECache to limit the number of cached grids kept in memory
|
||||
# 01/09/14 16952 randerso Fix regression made in #2517 which caused errors with overlapping grids
|
||||
# 02/04/14 17042 ryu Check in changes for randerso.
|
||||
# 04/11/2014 17242 David Gillingham (code checked in by zhao)
|
||||
#
|
||||
|
||||
BATCH_DELAY = 0.0
|
||||
|
@ -908,8 +909,7 @@ class IscMosaic:
|
|||
destGrid, history = grid
|
||||
self.__dbGrid = (destGrid, history, tr)
|
||||
else:
|
||||
self.logProblem("Unable to access grid for ",
|
||||
self.__printTR(tr), "for ", self.__parmName)
|
||||
logger.error("Unable to access grid for "+self.__printTR(tr) +" for " + self.__parmName)
|
||||
return None
|
||||
|
||||
return (self.__dbGrid[0], self.__dbGrid[1])
|
||||
|
|
|
@ -51,6 +51,7 @@ from com.raytheon.uf.common.localization import LocalizationContext_Localization
|
|||
# methods where it's needed.
|
||||
# 11/07/13 2517 randerso Allow getLogger to override logLevel
|
||||
# 01/22/14/ 2504 randerso Added hostname to log path
|
||||
# 04/10/2014 17241 David Gillingham (code checked in by zhao)
|
||||
#
|
||||
#
|
||||
|
||||
|
@ -297,8 +298,12 @@ def getLogger(scriptName, logName=None, logLevel=logging.INFO):
|
|||
|
||||
logFile = os.path.join(logPath, logName)
|
||||
|
||||
if not os.path.exists(logPath):
|
||||
try:
|
||||
os.makedirs(logPath)
|
||||
except OSError as e:
|
||||
import errno
|
||||
if e.errno != errno.EEXIST:
|
||||
raise e
|
||||
|
||||
theLog = logging.getLogger(scriptName)
|
||||
theLog.setLevel(logLevel)
|
||||
|
|
|
@ -57,36 +57,41 @@ import com.raytheon.uf.common.util.ArraysUtil;
|
|||
import com.raytheon.uf.common.util.header.WMOHeaderFinder;
|
||||
|
||||
/**
|
||||
* Decoder implementation for satellite plugin.
|
||||
* Decodes GINI formatted satelitte data into {@link SatelliteRecord}s.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ----------- ---------- ----------- --------------------------
|
||||
* 006 garmenda Initial Creation
|
||||
* /14/2007 139 Phillippe Modified to follow refactored plugin pattern
|
||||
* 8/30/07 njensen Added units, commented out data that
|
||||
* is currently decoded but not used.
|
||||
* 12/01/07 555 garmendariz Modified decompress method.
|
||||
* 12/06/07 555 garmendariz Modifed start point to remove satellite header
|
||||
* Dec 17, 2007 600 bphillip Added dao pool usage
|
||||
* 04Apr2008 1068 MW Fegan Modified decompression routine to prevent
|
||||
* process hang-up.
|
||||
* 11/11/2008 chammack Refactored to be thread safe in camel
|
||||
* 02/05/2010 4120 jkorman Modified removeWmoHeader to handle WMOHeader in
|
||||
* various start locations.
|
||||
* 04/17/2012 14724 kshresth This is a temporary workaround - Projection off CONUS
|
||||
* - AWIPS2 Baseline Repository --------
|
||||
* 06/27/2012 798 jkorman Using SatelliteMessageData to "carry" the decoded image.
|
||||
* 01/03/2013 15294 D. Friedman Start with File instead of byte[] to
|
||||
* reduce memory usage.
|
||||
* Feb 15, 2013 1638 mschenke Moved array based utilities from Util into ArraysUtil
|
||||
*
|
||||
* Mar 19, 2013 1785 bgonzale Added performance status handler and added status
|
||||
* to decode.
|
||||
* Jan 20, 2014 njensen Better error handling when fields are not recognized
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- ----------- -----------------------------------------
|
||||
* 2006 garmenda Initial Creation
|
||||
* Feb 14, 2007 139 Phillippe Modified to follow refactored plugin
|
||||
* pattern
|
||||
* Aug 30, 2007 njensen Added units, commented out data that is
|
||||
* currently decoded but not used.
|
||||
* Dec 01, 2007 555 garmendariz Modified decompress method.
|
||||
* DEc 06, 2007 555 garmendariz Modifed start point to remove satellite
|
||||
* header
|
||||
* Dec 17, 2007 600 bphillip Added dao pool usage
|
||||
* Apr 04, 2008 1068 MW Fegan Modified decompression routine to prevent
|
||||
* process hang-up.
|
||||
* Nov 11, 2008 chammack Refactored to be thread safe in camel
|
||||
* Feb 05, 2010 4120 jkorman Modified removeWmoHeader to handle
|
||||
* WMOHeader in various start locations.
|
||||
* Apr 17, 2012 14724 kshresth This is a temporary workaround -
|
||||
* Projection off CONUS
|
||||
* Jun 27, 2012 798 jkorman Using SatelliteMessageData to "carry" the
|
||||
* decoded image.
|
||||
* Jan 03, 2013 15294 D. Friedman Start with File instead of byte[] to
|
||||
* reduce memory usage.
|
||||
* Feb 15, 2013 1638 mschenke Moved array based utilities from Util
|
||||
* into ArraysUtil
|
||||
* Mar 19, 2013 1785 bgonzale Added performance status handler and
|
||||
* added status to decode.
|
||||
* Jan 20, 2014 2359 njensen Better error handling when fields are not
|
||||
* recognized
|
||||
* Apr 15, 2014 3017 bsteffen Call new methods in SatSpatialFactory
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -369,7 +374,10 @@ public class SatelliteDecoder {
|
|||
// get the scanning mode
|
||||
scanMode = byteBuffer.get(37);
|
||||
|
||||
float dx = 0.0f, dy = 0.0f, lov = 0.0f, lo2 = 0.0f, la2 = 0.0f;
|
||||
float dx = 0.0f;
|
||||
float dy = 0.0f;
|
||||
|
||||
SatMapCoverage mapCoverage = null;
|
||||
// Do specialized decoding and retrieve spatial data for Lambert
|
||||
// Conformal and Polar Stereographic projections
|
||||
if ((mapProjection == SatSpatialFactory.PROJ_LAMBERT)
|
||||
|
@ -384,30 +392,7 @@ public class SatelliteDecoder {
|
|||
|
||||
byteBuffer.position(27);
|
||||
byteBuffer.get(threeBytesArray, 0, 3);
|
||||
lov = transformLongitude(threeBytesArray);
|
||||
}
|
||||
// Do specialized decoding and retrieve spatial data for
|
||||
// Mercator projection
|
||||
else if (mapProjection == SatSpatialFactory.PROJ_MERCATOR) {
|
||||
dx = byteBuffer.getShort(33);
|
||||
dy = byteBuffer.getShort(35);
|
||||
|
||||
byteBuffer.position(27);
|
||||
byteBuffer.get(threeBytesArray, 0, 3);
|
||||
la2 = transformLatitude(threeBytesArray);
|
||||
|
||||
byteBuffer.position(30);
|
||||
byteBuffer.get(threeBytesArray, 0, 3);
|
||||
lo2 = transformLongitude(threeBytesArray);
|
||||
|
||||
} else {
|
||||
throw new DecoderException(
|
||||
"Unable to decode GINI Satellite: Encountered Unknown projection");
|
||||
}
|
||||
|
||||
SatMapCoverage mapCoverage = null;
|
||||
|
||||
try {
|
||||
float lov = transformLongitude(threeBytesArray);
|
||||
/**
|
||||
* This is a temporary workaround for DR14724, hopefully to
|
||||
* be removed after NESDIS changes the product header
|
||||
|
@ -428,35 +413,39 @@ public class SatelliteDecoder {
|
|||
* End of DR14724
|
||||
*/
|
||||
mapCoverage = SatSpatialFactory.getInstance()
|
||||
.getMapCoverage(mapProjection, nx, ny, dx, dy, lov,
|
||||
.getCoverageSingleCorner(mapProjection, nx, ny,
|
||||
lov,
|
||||
latin, la1, lo1, dx, dy);
|
||||
}
|
||||
// Do specialized decoding and retrieve spatial data for
|
||||
// Mercator projection
|
||||
else if (mapProjection == SatSpatialFactory.PROJ_MERCATOR) {
|
||||
dx = byteBuffer.getShort(33);
|
||||
dy = byteBuffer.getShort(35);
|
||||
|
||||
byteBuffer.position(27);
|
||||
byteBuffer.get(threeBytesArray, 0, 3);
|
||||
float la2 = transformLatitude(threeBytesArray);
|
||||
|
||||
byteBuffer.position(30);
|
||||
byteBuffer.get(threeBytesArray, 0, 3);
|
||||
float lo2 = transformLongitude(threeBytesArray);
|
||||
mapCoverage = SatSpatialFactory.getInstance()
|
||||
.getCoverageTwoCorners(mapProjection, nx, ny, 0.0f,
|
||||
latin, la1, lo1, la2, lo2);
|
||||
} catch (Exception e) {
|
||||
StringBuffer buf = new StringBuffer();
|
||||
buf.append(
|
||||
"Error getting or constructing SatMapCoverage for values: ")
|
||||
.append("\n\t");
|
||||
buf.append("mapProjection=" + mapProjection).append("\n\t");
|
||||
buf.append("nx=" + nx).append("\n\t");
|
||||
buf.append("ny=" + ny).append("\n\t");
|
||||
buf.append("dx=" + dx).append("\n\t");
|
||||
buf.append("dy=" + dy).append("\n\t");
|
||||
buf.append("lov=" + lov).append("\n\t");
|
||||
buf.append("latin=" + latin).append("\n\t");
|
||||
buf.append("la1=" + la1).append("\n\t");
|
||||
buf.append("lo1=" + lo1).append("\n\t");
|
||||
buf.append("la2=" + la2).append("\n\t");
|
||||
buf.append("lo2=" + lo2).append("\n");
|
||||
throw new DecoderException(buf.toString(), e);
|
||||
|
||||
} else {
|
||||
throw new DecoderException(
|
||||
"Unable to decode GINI Satellite: Encountered Unknown projection: "
|
||||
+ mapProjection);
|
||||
}
|
||||
|
||||
if (record != null) {
|
||||
record.setTraceId(traceId);
|
||||
record.setCoverage(mapCoverage);
|
||||
// Create the data record.
|
||||
IDataRecord dataRec = messageData.getStorageRecord(record,
|
||||
SatelliteRecord.SAT_DATASET_NAME);
|
||||
record.setMessageData(dataRec);
|
||||
}
|
||||
record.setTraceId(traceId);
|
||||
record.setCoverage(mapCoverage);
|
||||
// Create the data record.
|
||||
IDataRecord dataRec = messageData.getStorageRecord(record,
|
||||
SatelliteRecord.SAT_DATASET_NAME);
|
||||
record.setMessageData(dataRec);
|
||||
}
|
||||
timer.stop();
|
||||
perfLog.logDuration("Time to Decode", timer.getElapsedTime());
|
||||
|
|
|
@ -20,21 +20,15 @@
|
|||
|
||||
package com.raytheon.edex.util.satellite;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.geotools.geometry.DirectPosition2D;
|
||||
import org.geotools.geometry.jts.JTS;
|
||||
import org.opengis.referencing.crs.ProjectedCRS;
|
||||
import org.opengis.referencing.operation.MathTransform;
|
||||
|
||||
import com.raytheon.edex.exception.DecoderException;
|
||||
import com.raytheon.edex.plugin.satellite.dao.SatMapCoverageDao;
|
||||
import com.raytheon.uf.common.dataplugin.satellite.SatMapCoverage;
|
||||
import com.raytheon.uf.common.geospatial.MapUtil;
|
||||
import com.raytheon.uf.edex.database.DataAccessLayerException;
|
||||
import com.vividsolutions.jts.geom.Coordinate;
|
||||
import com.vividsolutions.jts.geom.Envelope;
|
||||
import com.vividsolutions.jts.geom.GeometryFactory;
|
||||
import com.vividsolutions.jts.geom.Polygon;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -42,12 +36,14 @@ import com.vividsolutions.jts.geom.Polygon;
|
|||
*
|
||||
* <pre>
|
||||
* SOFTWARE HISTORY
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* 12/19/07 439 bphillip Initial creation
|
||||
* - AWIPS2 Baseline Repository --------
|
||||
* 07/12/2012 798 jkorman Changed projection "magic" numbers
|
||||
* 09/30/2013 2333 mschenke Refactored to store points in crs space
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- ----------- --------------------------
|
||||
* Dec 19, 2007 439 bphillip Initial creation
|
||||
* Jul 12, 2012 798 jkorman Changed projection "magic" numbers
|
||||
* Sep 30, 2013 2333 mschenke Refactored to store points in crs space
|
||||
* Apr 15, 2014 3017 bsteffen Add new getCoverage methods to support
|
||||
* either one corner + dx/dy or two corners.
|
||||
*
|
||||
* </pre>
|
||||
*/
|
||||
public class SatSpatialFactory {
|
||||
|
@ -66,9 +62,6 @@ public class SatSpatialFactory {
|
|||
|
||||
public static final int UNDEFINED = -1;
|
||||
|
||||
/** The logger */
|
||||
private Log logger = LogFactory.getLog(getClass());
|
||||
|
||||
/** The singleton instance */
|
||||
private static SatSpatialFactory instance;
|
||||
|
||||
|
@ -87,7 +80,11 @@ public class SatSpatialFactory {
|
|||
}
|
||||
|
||||
/**
|
||||
* Retrieves or generates a satellite map coverage object
|
||||
* @deprecated use either
|
||||
* {@link #getCoverageSingleCorner(int, int, int, double, double, double, double, double, double)}
|
||||
* or
|
||||
* {@link #getCoverageTwoCorners(int, int, int, double, double, double, double, double, double)}
|
||||
* depending on which parameters are considered more accurate.
|
||||
*
|
||||
* @param mapProjection
|
||||
* The projection
|
||||
|
@ -117,169 +114,231 @@ public class SatSpatialFactory {
|
|||
* If errors occur during db interaction or creation of the
|
||||
* coverage object
|
||||
*/
|
||||
@Deprecated
|
||||
public synchronized SatMapCoverage getMapCoverage(Integer mapProjection,
|
||||
Integer nx, Integer ny, Float dx, Float dy, Float lov, Float latin,
|
||||
Float la1, Float lo1, Float la2, Float lo2) throws Exception {
|
||||
try {
|
||||
SatMapCoverage mapCoverage = createMapCoverage(mapProjection, nx,
|
||||
ny, dx, dy, lov, latin, la1, lo1, la2, lo2);
|
||||
SatMapCoverage persisted = satDao
|
||||
.queryByMapId(mapCoverage.getGid());
|
||||
if (persisted == null) {
|
||||
persisted = mapCoverage;
|
||||
satDao.persist(persisted);
|
||||
}
|
||||
return persisted;
|
||||
} catch (Exception e) {
|
||||
throw new DataAccessLayerException(
|
||||
"Unable to retrieve or construct valid Satellite Map Coverage",
|
||||
e);
|
||||
if (mapProjection == PROJ_MERCATOR) {
|
||||
return getCoverageTwoCorners(mapProjection, nx, ny, lov, latin,
|
||||
la1, lo1, la2, lo2);
|
||||
} else {
|
||||
return getCoverageSingleCorner(mapProjection, nx, ny, lov, latin,
|
||||
la1, lo1, dx, dy);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new SatMapCoverage object from scratch with the given
|
||||
* parameters
|
||||
* Create a {@link SatMapCoverage} with an area defined by only one corner
|
||||
* and using dx/dy and nx/by to derive the rest of the area. If dx and dy
|
||||
* are positive than la1 and lo1 are the upper left corner.
|
||||
*
|
||||
* @param mapProjection
|
||||
* The projection
|
||||
* @param crsType
|
||||
* the type of CRS, must be one of
|
||||
* {@link #PROJ_CYLIN_EQUIDISTANT}, {@link #PROJ_LAMBERT},
|
||||
* {@link #PROJ_MERCATOR}, {@link #PROJ_POLAR}.
|
||||
* @param nx
|
||||
* The number of columns
|
||||
* the number of columns of data.
|
||||
* @param ny
|
||||
* The number of rows
|
||||
* @param dx
|
||||
* The distance between x points
|
||||
* @param dy
|
||||
* The distance between y points
|
||||
* the number of rows of data.
|
||||
* @param lov
|
||||
* The orientation of the grid
|
||||
* the longitude orientatition, used by
|
||||
* {@link #PROJ_CYLIN_EQUIDISTANT}, {@link #PROJ_LAMBERT},
|
||||
* {@link #PROJ_POLAR}.
|
||||
* @param latin
|
||||
* The latitude at which the Lambert projection cone is tangent
|
||||
* to the earth
|
||||
* the latitude at which the projection is tangent to the earths
|
||||
* surface, used by {@link #PROJ_CYLIN_EQUIDISTANT},
|
||||
* {@link #PROJ_LAMBERT}, {@link #PROJ_MERCATOR}.
|
||||
* @param la1
|
||||
* Latitude of first point
|
||||
* the latitude of a corner of the grid, if dy is positive this
|
||||
* is an upper corner.
|
||||
* @param lo1
|
||||
* Longitude of first point
|
||||
* @param la2
|
||||
* Latitude of last point
|
||||
* @param lo2
|
||||
* Longitude of last point
|
||||
* @return A SatMapCoverage object with the given values
|
||||
* @throws Exception
|
||||
* If errors occur during generation of the coverage object
|
||||
* the longitide of a corner of the grid, if dx is positive this
|
||||
* is a left corner
|
||||
* @param dx
|
||||
* the distance between columns measured in CRS meters.
|
||||
* @param dy
|
||||
* the distance between rows measured in CRS meters.
|
||||
* @return a {@link SatMapCoverage} matching these parameters that has been
|
||||
* loaded from or persisted to the database.
|
||||
* @throws DecoderException
|
||||
*/
|
||||
private synchronized SatMapCoverage createMapCoverage(
|
||||
Integer mapProjection, Integer nx, Integer ny, Float dx, Float dy,
|
||||
Float lov, Float latin, Float la1, Float lo1, Float la2, Float lo2)
|
||||
throws Exception {
|
||||
public SatMapCoverage getCoverageSingleCorner(int crsType, int nx, int ny,
|
||||
double lov, double latin, double la1, double lo1, double dx,
|
||||
double dy) throws DecoderException {
|
||||
try {
|
||||
ProjectedCRS crs = createCRS(crsType, lov, latin, 0.0);
|
||||
DirectPosition2D corner = new DirectPosition2D(lo1, la1);
|
||||
MathTransform fromLatLon = MapUtil.getTransformFromLatLon(crs);
|
||||
fromLatLon.transform(corner, corner);
|
||||
Envelope e = new Envelope(corner.x, corner.x, corner.y, corner.y);
|
||||
e.expandToInclude(corner.x + dx * nx, corner.y + dy * ny);
|
||||
SatMapCoverage coverage = createCoverageFromEnvelope(crsType, crs,
|
||||
e, nx, ny);
|
||||
return checkPersisted(coverage);
|
||||
} catch (Exception e) {
|
||||
StringBuilder buf = new StringBuilder();
|
||||
buf.append(
|
||||
"Error getting or constructing SatMapCoverage for values: ")
|
||||
.append("\n\t");
|
||||
buf.append("crsType=" + crsType).append("\n\t");
|
||||
buf.append("nx=" + nx).append("\n\t");
|
||||
buf.append("ny=" + ny).append("\n\t");
|
||||
buf.append("lov=" + lov).append("\n\t");
|
||||
buf.append("latin=" + latin).append("\n\t");
|
||||
buf.append("la1=" + la1).append("\n\t");
|
||||
buf.append("lo1=" + lo1).append("\n\t");
|
||||
buf.append("dx=" + dx).append("\n\t");
|
||||
buf.append("dy=" + dy).append("\n");
|
||||
throw new DecoderException(buf.toString(), e);
|
||||
}
|
||||
}
|
||||
|
||||
logger.debug("Creating map coverage object");
|
||||
|
||||
ProjectedCRS crs = null;
|
||||
// Get the correct CRS
|
||||
if (mapProjection == PROJ_MERCATOR) {
|
||||
/**
|
||||
*
|
||||
* Create a {@link SatMapCoverage} with an area defined by two corners. The
|
||||
* two corners must be opposite(diagnol) from eachother. They caan be either
|
||||
* the upper left and lower right or the upper right and lower left corners.
|
||||
*
|
||||
* @param crsType
|
||||
* the type of CRS, must be one of
|
||||
* {@link #PROJ_CYLIN_EQUIDISTANT}, {@link #PROJ_LAMBERT},
|
||||
* {@link #PROJ_MERCATOR}, {@link #PROJ_POLAR}.
|
||||
* @param lov
|
||||
* the longitude orientatition, used by
|
||||
* {@link #PROJ_CYLIN_EQUIDISTANT}, {@link #PROJ_LAMBERT},
|
||||
* {@link #PROJ_POLAR}.
|
||||
* @param latin
|
||||
* the latitude at which the projection is tangent to the earths
|
||||
* surface, used by {@link #PROJ_CYLIN_EQUIDISTANT},
|
||||
* {@link #PROJ_LAMBERT}, {@link #PROJ_MERCATOR}.
|
||||
* @param la1
|
||||
* the latitude of a corner of the grid.
|
||||
* @param lo1
|
||||
* the longitide of a corner of the grid.
|
||||
* @param la2
|
||||
* the latitude of a corner of the grid., should be opposite
|
||||
* corner from la1.
|
||||
* @param lo2
|
||||
* the longitide of a corner of the grid, should be opposite
|
||||
* corner from lo1
|
||||
* @return a {@link SatMapCoverage} matching these parameters that has been
|
||||
* loaded from or persisted to the database.
|
||||
* @throws DecoderException
|
||||
*/
|
||||
public SatMapCoverage getCoverageTwoCorners(int crsType, int nx, int ny,
|
||||
double lov, double latin, double la1, double lo1, double la2,
|
||||
double lo2) throws DecoderException {
|
||||
try {
|
||||
double cm = 0.0;
|
||||
if ((lo1 > 0.0) && (lo2 < 0.0)) {
|
||||
cm = 180.0;
|
||||
}
|
||||
crs = MapUtil.constructMercator(MapUtil.AWIPS_EARTH_RADIUS,
|
||||
MapUtil.AWIPS_EARTH_RADIUS, latin, cm);
|
||||
} else if (mapProjection == PROJ_LAMBERT) {
|
||||
crs = MapUtil.constructLambertConformal(MapUtil.AWIPS_EARTH_RADIUS,
|
||||
MapUtil.AWIPS_EARTH_RADIUS, latin, latin, lov);
|
||||
} else if (mapProjection == SatSpatialFactory.PROJ_CYLIN_EQUIDISTANT) {
|
||||
crs = MapUtil.constructEquidistantCylindrical(
|
||||
MapUtil.AWIPS_EARTH_RADIUS, MapUtil.AWIPS_EARTH_RADIUS,
|
||||
lov, latin);
|
||||
} else {
|
||||
crs = MapUtil.constructNorthPolarStereo(MapUtil.AWIPS_EARTH_RADIUS,
|
||||
MapUtil.AWIPS_EARTH_RADIUS, 60, lov);
|
||||
}
|
||||
|
||||
DirectPosition2D firstPosition = null;
|
||||
DirectPosition2D secondPosition = null;
|
||||
DirectPosition2D thirdPosition = null;
|
||||
DirectPosition2D fourthPosition = null;
|
||||
DirectPosition2D corner1 = new DirectPosition2D();
|
||||
DirectPosition2D corner2 = new DirectPosition2D();
|
||||
DirectPosition2D corner3 = new DirectPosition2D();
|
||||
DirectPosition2D corner4 = new DirectPosition2D();
|
||||
|
||||
/*
|
||||
* Projection is Mercator. Determine corner points from la1,lo1,la2,lo2
|
||||
* provided in the satellite file
|
||||
*/
|
||||
if (mapProjection == PROJ_MERCATOR) {
|
||||
logger.debug("Determining corner points for Mercator projection");
|
||||
corner1.x = lo1;
|
||||
corner1.y = la1;
|
||||
|
||||
corner3.x = lo2;
|
||||
corner3.y = la2;
|
||||
|
||||
corner2.x = lo2;
|
||||
corner2.y = la1;
|
||||
|
||||
corner4.x = lo1;
|
||||
corner4.y = la2;
|
||||
}
|
||||
/*
|
||||
* Projection is Lambert Conformal or Polar Stereographic. Therefore,
|
||||
* the corner points must be calculated
|
||||
*/
|
||||
else {
|
||||
logger.debug("Determining corner points for Lambert Conformal or Polar Stereographic projection");
|
||||
|
||||
// Get the transforms to be used to convert between meters and
|
||||
// lat/lon
|
||||
ProjectedCRS crs = createCRS(crsType, lov, latin, cm);
|
||||
DirectPosition2D corner1 = new DirectPosition2D(lo1, la1);
|
||||
DirectPosition2D corner2 = new DirectPosition2D(lo2, la2);
|
||||
MathTransform fromLatLon = MapUtil.getTransformFromLatLon(crs);
|
||||
MathTransform toLatLon = fromLatLon.inverse();
|
||||
|
||||
// Use la1 and lo1 to specifyt the first point
|
||||
firstPosition = new DirectPosition2D();
|
||||
fromLatLon.transform(new DirectPosition2D(lo1, la1), firstPosition);
|
||||
|
||||
// Determine the 3 other corner points using the given dx,dy,nx, and
|
||||
// ny in meters
|
||||
secondPosition = new DirectPosition2D(firstPosition.x + (dx * nx),
|
||||
firstPosition.y);
|
||||
thirdPosition = new DirectPosition2D(secondPosition.x,
|
||||
firstPosition.y + (dy * ny));
|
||||
fourthPosition = new DirectPosition2D(firstPosition.x,
|
||||
thirdPosition.y);
|
||||
|
||||
// Convert the corner points from meters to lat/lon
|
||||
toLatLon.transform(firstPosition, corner1);
|
||||
toLatLon.transform(secondPosition, corner2);
|
||||
toLatLon.transform(thirdPosition, corner3);
|
||||
toLatLon.transform(fourthPosition, corner4);
|
||||
fromLatLon.transform(corner1, corner1);
|
||||
fromLatLon.transform(corner2, corner2);
|
||||
Envelope e = new Envelope(corner1.x, corner2.x, corner1.y,
|
||||
corner2.y);
|
||||
SatMapCoverage coverage = createCoverageFromEnvelope(crsType, crs,
|
||||
e, nx, ny);
|
||||
return checkPersisted(coverage);
|
||||
} catch (Exception e) {
|
||||
StringBuilder buf = new StringBuilder();
|
||||
buf.append(
|
||||
"Error getting or constructing SatMapCoverage for values: ")
|
||||
.append("\n\t");
|
||||
buf.append("crsType=" + crsType).append("\n\t");
|
||||
buf.append("nx=" + nx).append("\n\t");
|
||||
buf.append("ny=" + ny).append("\n\t");
|
||||
buf.append("lov=" + lov).append("\n\t");
|
||||
buf.append("latin=" + latin).append("\n\t");
|
||||
buf.append("la1=" + la1).append("\n\t");
|
||||
buf.append("lo1=" + lo1).append("\n\t");
|
||||
buf.append("la2=" + la2).append("\n\t");
|
||||
buf.append("lo2=" + lo2).append("\n");
|
||||
throw new DecoderException(buf.toString(), e);
|
||||
}
|
||||
}
|
||||
|
||||
double[] c = corner1.getCoordinate();
|
||||
Coordinate c1 = new Coordinate(c[0], c[1]);
|
||||
c = corner2.getCoordinate();
|
||||
Coordinate c2 = new Coordinate(c[0], c[1]);
|
||||
c = corner3.getCoordinate();
|
||||
Coordinate c3 = new Coordinate(c[0], c[1]);
|
||||
c = corner4.getCoordinate();
|
||||
Coordinate c4 = new Coordinate(c[0], c[1]);
|
||||
|
||||
// Go from lat/lon to crs space to get minX,minY in crs space
|
||||
GeometryFactory gf = new GeometryFactory();
|
||||
Polygon polygon = gf.createPolygon(
|
||||
gf.createLinearRing(new Coordinate[] { c1, c2, c3, c4, c1 }),
|
||||
null);
|
||||
MathTransform fromLatLon = MapUtil.getTransformFromLatLon(crs);
|
||||
|
||||
polygon = (Polygon) JTS.transform(polygon, fromLatLon);
|
||||
Envelope env = polygon.getEnvelopeInternal();
|
||||
if (mapProjection == PROJ_MERCATOR) {
|
||||
// Calculate dx/dy in mercator crs space
|
||||
dx = (float) (env.getWidth() / nx);
|
||||
dy = (float) (env.getHeight() / ny);
|
||||
/** Load or persist a {@link SatMapCoverage} */
|
||||
private synchronized SatMapCoverage checkPersisted(
|
||||
SatMapCoverage mapCoverage) {
|
||||
SatMapCoverage persisted = satDao.queryByMapId(mapCoverage.getGid());
|
||||
if (persisted == null) {
|
||||
persisted = mapCoverage;
|
||||
satDao.persist(persisted);
|
||||
}
|
||||
return new SatMapCoverage(mapProjection, env.getMinX(), env.getMinY(),
|
||||
nx, ny, dx, dy, crs);
|
||||
return persisted;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a SatMapCoverage from an envelope and additional metadata. The
|
||||
* minX and minY from the envelope are used and dx/dy are derived useing the
|
||||
* envelope dimensions and nx/ny.
|
||||
*/
|
||||
private static SatMapCoverage createCoverageFromEnvelope(int crsType,
|
||||
ProjectedCRS crs, Envelope envelope, int nx, int ny) {
|
||||
float dx = (float) (envelope.getWidth() / nx);
|
||||
float dy = (float) (envelope.getWidth() / nx);
|
||||
return new SatMapCoverage(crsType, envelope.getMinX(),
|
||||
envelope.getMinY(), nx, ny, dx, dy, crs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a {@link ProjectedCRS} from a crsType and some parameters.
|
||||
*
|
||||
* @param crsType
|
||||
* the type of CRS, must be one of
|
||||
* {@link #PROJ_CYLIN_EQUIDISTANT}, {@link #PROJ_LAMBERT},
|
||||
* {@link #PROJ_MERCATOR}, {@link #PROJ_POLAR}. * @param lov
|
||||
* @param lov
|
||||
* the longitude orientatition, used by
|
||||
* {@link #PROJ_CYLIN_EQUIDISTANT}, {@link #PROJ_LAMBERT},
|
||||
* {@link #PROJ_POLAR}.
|
||||
* @param latin
|
||||
* the latitude at which the projection is tangent to the earths
|
||||
* surface, used by {@link #PROJ_CYLIN_EQUIDISTANT},
|
||||
* {@link #PROJ_LAMBERT}, {@link #PROJ_MERCATOR}.
|
||||
* @param cm
|
||||
* the central meridian of the projection, only used by
|
||||
* {@link #PROJ_MERCATOR}.
|
||||
* @return
|
||||
*/
|
||||
private static ProjectedCRS createCRS(int crsType, double lov,
|
||||
double latin, double cm) {
|
||||
switch (crsType) {
|
||||
case PROJ_MERCATOR:
|
||||
return createMercatorCrs(latin, cm);
|
||||
case PROJ_LAMBERT:
|
||||
return createLambertCrs(latin, lov);
|
||||
case PROJ_CYLIN_EQUIDISTANT:
|
||||
return createEqCylCrs(latin, lov);
|
||||
default:
|
||||
return createNorthPolarStereoCrs(lov);
|
||||
}
|
||||
}
|
||||
|
||||
private static ProjectedCRS createMercatorCrs(double latin, double cm) {
|
||||
return MapUtil.constructMercator(MapUtil.AWIPS_EARTH_RADIUS,
|
||||
MapUtil.AWIPS_EARTH_RADIUS, latin, cm);
|
||||
}
|
||||
|
||||
private static ProjectedCRS createLambertCrs(double latin, double lov) {
|
||||
return MapUtil.constructLambertConformal(MapUtil.AWIPS_EARTH_RADIUS,
|
||||
MapUtil.AWIPS_EARTH_RADIUS, latin, latin, lov);
|
||||
}
|
||||
|
||||
private static ProjectedCRS createEqCylCrs(double latin, double lov) {
|
||||
return MapUtil.constructEquidistantCylindrical(
|
||||
MapUtil.AWIPS_EARTH_RADIUS, MapUtil.AWIPS_EARTH_RADIUS, lov,
|
||||
latin);
|
||||
}
|
||||
|
||||
private static ProjectedCRS createNorthPolarStereoCrs(double lov) {
|
||||
return MapUtil.constructNorthPolarStereo(MapUtil.AWIPS_EARTH_RADIUS,
|
||||
MapUtil.AWIPS_EARTH_RADIUS, 60, lov);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -57,6 +57,7 @@ import com.raytheon.uf.common.colormap.prefs.ColorMapParameters;
|
|||
* Aug 13, 2010 mschenke Initial creation
|
||||
* Feb 15, 2013 1638 mschenke Moved IndexColorModel creation to common.colormap utility
|
||||
* Nov 4, 2013 2492 mschenke Rewritten to model glsl equivalent
|
||||
* Apr 15, 2014 3016 randerso Check in Max's fix for getColorByIndex
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -241,7 +242,7 @@ public class Colormapper {
|
|||
rangeMin = rangeMax;
|
||||
rangeMax = tmp;
|
||||
}
|
||||
|
||||
|
||||
double index = 0.0;
|
||||
// Flag if min/max values are on opposite sides of zero
|
||||
boolean minMaxOpposite = (cmapMin < 0 && cmapMax > 0)
|
||||
|
@ -384,8 +385,15 @@ public class Colormapper {
|
|||
* high.getAlpha());
|
||||
return new Color(r, g, b, a);
|
||||
} else {
|
||||
return colorMap.getColors().get(
|
||||
(int) (index * (colorMap.getSize() - 1)));
|
||||
int colorIndex = (int) (index * colorMap.getSize());
|
||||
|
||||
if (colorIndex < 0) {
|
||||
colorIndex = 0;
|
||||
} else if (colorIndex >= colorMap.getSize()) {
|
||||
colorIndex = colorMap.getSize() - 1;
|
||||
}
|
||||
|
||||
return colorMap.getColors().get(colorIndex);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -43,4 +43,6 @@ public class RegistryAvailability {
|
|||
|
||||
/** Registry not available since the database is not yet initialized */
|
||||
public static final String DB_NOT_INITIALIZED = "Registry database and services are currently initializing!";
|
||||
|
||||
public static final String SYNC_IN_PROGRESS = "Registry currently being synchronized";
|
||||
}
|
||||
|
|
|
@ -53,8 +53,8 @@ public class ReplicationEventDao extends
|
|||
}
|
||||
|
||||
@Transactional(propagation = Propagation.MANDATORY, readOnly = true)
|
||||
public List<ReplicationEvent> getReplicationEvents(String remoteRegistry) {
|
||||
public List<ReplicationEvent> getReplicationEvents(String remoteRegistry, int batchSize) {
|
||||
return this.executeHQLQuery(String.format(GET_REPLICATION_EVENT_QUERY,
|
||||
remoteRegistry, remoteRegistry));
|
||||
remoteRegistry, remoteRegistry),batchSize);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -104,7 +104,6 @@ import com.raytheon.uf.edex.registry.ebxml.dao.DbInit;
|
|||
import com.raytheon.uf.edex.registry.ebxml.dao.RegistryDao;
|
||||
import com.raytheon.uf.edex.registry.ebxml.dao.RegistryObjectDao;
|
||||
import com.raytheon.uf.edex.registry.ebxml.exception.EbxmlRegistryException;
|
||||
import com.raytheon.uf.edex.registry.ebxml.exception.NoReplicationServersAvailableException;
|
||||
import com.raytheon.uf.edex.registry.ebxml.init.RegistryInitializedListener;
|
||||
import com.raytheon.uf.edex.registry.ebxml.services.query.QueryConstants;
|
||||
import com.raytheon.uf.edex.registry.ebxml.services.query.RegistryQueryUtil;
|
||||
|
@ -153,6 +152,7 @@ import com.raytheon.uf.edex.registry.events.CreateAuditTrailEvent;
|
|||
* 1/21/2014 2613 bphillip Changed max down time which requires a sync
|
||||
* Feb 11, 2014 2771 bgonzale Use Data Delivery ID instead of Site.
|
||||
* 2/13/2014 2769 bphillip Refactored registry sync. Created quartz tasks to monitor registry uptime as well as subscription integrity
|
||||
* 4/11/2014 3011 bphillip Removed automatic registry sync check on startup
|
||||
* </pre>
|
||||
*
|
||||
* @author bphillip
|
||||
|
@ -167,6 +167,9 @@ public class RegistryFederationManager implements IRegistryFederationManager,
|
|||
protected static final IUFStatusHandler statusHandler = UFStatus
|
||||
.getHandler(RegistryFederationManager.class);
|
||||
|
||||
private static final transient IUFStatusHandler monitorHandler = UFStatus
|
||||
.getMonitorHandler(RegistryFederationManager.class);
|
||||
|
||||
/** Query used for synchronizing registries */
|
||||
private static final String SYNC_QUERY = "FROM RegistryObjectType obj where obj.id in (%s) order by obj.id asc";
|
||||
|
||||
|
@ -196,7 +199,16 @@ public class RegistryFederationManager implements IRegistryFederationManager,
|
|||
* The maximum time a registry can be down before a full synchronization is
|
||||
* performed
|
||||
*/
|
||||
private static final long MAX_DOWN_TIME_DURATION = TimeUtil.MILLIS_PER_HOUR * 6;
|
||||
private static final long MAX_DOWN_TIME_DURATION = TimeUtil.MILLIS_PER_HOUR * 48;
|
||||
|
||||
private static final String SYNC_WARNING_MSG = "Registry is out of sync with federation. Registry Synchronization required. Go to: ["
|
||||
+ RegistryUtil.LOCAL_REGISTRY_ADDRESS
|
||||
+ "/registry/federation/status.html] to synchronize.";
|
||||
|
||||
private static volatile boolean SYNC_NECESSARY = false;
|
||||
|
||||
public static AtomicBoolean SYNC_IN_PROGRESS = new AtomicBoolean(
|
||||
false);
|
||||
|
||||
/** Cutoff parameter for the query to get the expired events */
|
||||
private static final String GET_EXPIRED_EVENTS_QUERY_CUTOFF_PARAMETER = "cutoff";
|
||||
|
@ -205,9 +217,6 @@ public class RegistryFederationManager implements IRegistryFederationManager,
|
|||
private static final String GET_EXPIRED_EVENTS_QUERY = "FROM ReplicationEvent event where event.eventTime < :"
|
||||
+ GET_EXPIRED_EVENTS_QUERY_CUTOFF_PARAMETER;
|
||||
|
||||
/** Maximum times this registry will try to sync data before failure */
|
||||
private int maxSyncRetries = 3;
|
||||
|
||||
/**
|
||||
* Denotes if initialization has already occurred for this class. It is a
|
||||
* static variable because at this time, multiple Spring containers load
|
||||
|
@ -320,8 +329,6 @@ public class RegistryFederationManager implements IRegistryFederationManager,
|
|||
if (!centralRegistry) {
|
||||
checkDownTime();
|
||||
}
|
||||
federatedRegistryMonitor.updateTime();
|
||||
|
||||
} catch (Exception e1) {
|
||||
throw new EbxmlRegistryException(
|
||||
"Error initializing RegistryReplicationManager", e1);
|
||||
|
@ -345,96 +352,24 @@ public class RegistryFederationManager implements IRegistryFederationManager,
|
|||
|
||||
/**
|
||||
* Checks how long a registry has been down. If the registry has been down
|
||||
* for over 2 days, the registry is synchronized with one of the federation
|
||||
* members
|
||||
* longer than the MAX_DOWN_TIME_DURATION, then a sync is necessary
|
||||
*
|
||||
* @see RegistryFederationManager.MAX_DOWN_TIME_DURATION
|
||||
* @throws Exception
|
||||
*/
|
||||
private void checkDownTime() throws Exception {
|
||||
long currentTime = TimeUtil.currentTimeMillis();
|
||||
long lastKnownUp = federatedRegistryMonitor.getLastKnownUptime();
|
||||
long downTime = currentTime - lastKnownUp;
|
||||
statusHandler
|
||||
.info("Registry has been down since: "
|
||||
+ new Date(currentTime - downTime)
|
||||
+ ". Checking if synchronization with the federation is necessary...");
|
||||
|
||||
// The registry has been down for ~2 days, this requires a
|
||||
// synchronization of the
|
||||
// data from the federation
|
||||
statusHandler.info("Registry has been down since: "
|
||||
+ new Date(currentTime - downTime));
|
||||
/*
|
||||
* The registry has been down for ~2 days, this requires a
|
||||
* synchronization of the data from the federation
|
||||
*/
|
||||
if (currentTime - lastKnownUp > MAX_DOWN_TIME_DURATION) {
|
||||
int syncAttempt = 1;
|
||||
for (; syncAttempt <= maxSyncRetries; syncAttempt++) {
|
||||
try {
|
||||
statusHandler
|
||||
.warn("Registry has been down for more than "
|
||||
+ (MAX_DOWN_TIME_DURATION / TimeUtil.MILLIS_PER_HOUR)
|
||||
+ " hours. Initiating federated registry data synchronization attempt #"
|
||||
+ syncAttempt + "/" + maxSyncRetries
|
||||
+ "...");
|
||||
if (CollectionUtil.isNullOrEmpty(servers
|
||||
.getRegistryReplicationServers())) {
|
||||
statusHandler
|
||||
.error("No servers configured for replication. Unable to synchronize registry data with federation!");
|
||||
break;
|
||||
} else {
|
||||
RegistryType registryToSyncFrom = null;
|
||||
for (String remoteRegistryId : servers
|
||||
.getRegistryReplicationServers()) {
|
||||
statusHandler.info("Checking availability of ["
|
||||
+ remoteRegistryId + "]...");
|
||||
RegistryType remoteRegistry = dataDeliveryRestClient
|
||||
.getRegistryObject(
|
||||
ncfAddress,
|
||||
remoteRegistryId
|
||||
+ FederationProperties.REGISTRY_SUFFIX);
|
||||
if (remoteRegistry == null) {
|
||||
statusHandler
|
||||
.warn("Registry at ["
|
||||
+ remoteRegistryId
|
||||
+ "] not found in federation. Unable to use as synchronization source.");
|
||||
} else if (dataDeliveryRestClient
|
||||
.isRegistryAvailable(remoteRegistry
|
||||
.getBaseURL())) {
|
||||
registryToSyncFrom = remoteRegistry;
|
||||
break;
|
||||
} else {
|
||||
statusHandler
|
||||
.info("Registry at ["
|
||||
+ remoteRegistryId
|
||||
+ "] is not available. Unable to use as synchronization source.");
|
||||
}
|
||||
}
|
||||
|
||||
// No available registry was found!
|
||||
if (registryToSyncFrom == null) {
|
||||
throw new NoReplicationServersAvailableException(
|
||||
"No available registries found! Registry data will not be synchronized with the federation!");
|
||||
} else {
|
||||
synchronizeWithRegistry(registryToSyncFrom.getId());
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// If no servers are found, don't retry, just throw the
|
||||
// exception
|
||||
if (e instanceof NoReplicationServersAvailableException) {
|
||||
throw e;
|
||||
}
|
||||
if (syncAttempt < maxSyncRetries) {
|
||||
statusHandler.error(
|
||||
"Federation registry data synchronization attempt #"
|
||||
+ syncAttempt + "/" + maxSyncRetries
|
||||
+ " failed! Retrying...", e);
|
||||
} else {
|
||||
statusHandler
|
||||
.fatal("Federation registry data synchronization has failed",
|
||||
e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
SYNC_NECESSARY = true;
|
||||
sendSyncMessage();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -586,33 +521,51 @@ public class RegistryFederationManager implements IRegistryFederationManager,
|
|||
@Transactional
|
||||
@GET
|
||||
@Path("synchronizeWithRegistry/{registryId}")
|
||||
public void synchronizeWithRegistry(
|
||||
@PathParam("registryId") String registryId) throws Exception {
|
||||
long start = TimeUtil.currentTimeMillis();
|
||||
RegistryType remoteRegistry = null;
|
||||
try {
|
||||
if (!registryId.endsWith(FederationProperties.REGISTRY_SUFFIX)) {
|
||||
registryId += FederationProperties.REGISTRY_SUFFIX;
|
||||
}
|
||||
remoteRegistry = dataDeliveryRestClient.getRegistryObject(
|
||||
ncfAddress, registryId);
|
||||
} catch (Exception e) {
|
||||
throw new EbxmlRegistryException(
|
||||
"Error retrieving info for remote registry [" + registryId
|
||||
+ "] ", e);
|
||||
}
|
||||
if (remoteRegistry == null) {
|
||||
throw new EbxmlRegistryException("Unable to synchronize with ["
|
||||
+ registryId + "]. Registry not found in federation");
|
||||
}
|
||||
String remoteRegistryUrl = remoteRegistry.getBaseURL();
|
||||
public void synchronizeWithRegistry(@PathParam("registryId")
|
||||
String registryId) throws Exception {
|
||||
if (SYNC_IN_PROGRESS.compareAndSet(false, true)) {
|
||||
try {
|
||||
monitorHandler.handle(Priority.WARN,
|
||||
"Synchronizing registry with [" + registryId + "]...");
|
||||
long start = TimeUtil.currentTimeMillis();
|
||||
RegistryType remoteRegistry = null;
|
||||
try {
|
||||
if (!registryId
|
||||
.endsWith(FederationProperties.REGISTRY_SUFFIX)) {
|
||||
registryId += FederationProperties.REGISTRY_SUFFIX;
|
||||
}
|
||||
remoteRegistry = dataDeliveryRestClient.getRegistryObject(
|
||||
ncfAddress, registryId);
|
||||
} catch (Exception e) {
|
||||
throw new EbxmlRegistryException(
|
||||
"Error retrieving info for remote registry ["
|
||||
+ registryId + "] ", e);
|
||||
}
|
||||
if (remoteRegistry == null) {
|
||||
throw new EbxmlRegistryException(
|
||||
"Unable to synchronize with [" + registryId
|
||||
+ "]. Registry not found in federation");
|
||||
}
|
||||
String remoteRegistryUrl = remoteRegistry.getBaseURL();
|
||||
|
||||
for (final String objectType : replicatedObjectTypes) {
|
||||
syncObjectType(objectType, remoteRegistryUrl);
|
||||
for (final String objectType : replicatedObjectTypes) {
|
||||
syncObjectType(objectType, remoteRegistryUrl);
|
||||
}
|
||||
SYNC_NECESSARY = false;
|
||||
federatedRegistryMonitor.updateTime();
|
||||
StringBuilder syncMsg = new StringBuilder();
|
||||
|
||||
syncMsg.append("Registry synchronization using [")
|
||||
.append(remoteRegistryUrl)
|
||||
.append("] completed successfully in ")
|
||||
.append((TimeUtil.currentTimeMillis() - start))
|
||||
.append(" ms");
|
||||
statusHandler.info(syncMsg.toString());
|
||||
monitorHandler.handle(Priority.WARN, syncMsg.toString());
|
||||
} finally {
|
||||
SYNC_IN_PROGRESS.set(false);
|
||||
}
|
||||
}
|
||||
statusHandler.info("Registry synchronization using ["
|
||||
+ remoteRegistryUrl + "] completed successfully in "
|
||||
+ (TimeUtil.currentTimeMillis() - start) + " ms");
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -658,6 +611,8 @@ public class RegistryFederationManager implements IRegistryFederationManager,
|
|||
int remainder = remoteIds.size() % SYNC_BATCH_SIZE;
|
||||
|
||||
for (int currentBatch = 0; currentBatch < batches; currentBatch++) {
|
||||
statusHandler.info("Processing batch " + (currentBatch + 1)
|
||||
+ "/" + batches);
|
||||
persistBatch(objectType, remoteRegistryUrl, remoteIds.subList(
|
||||
currentBatch * SYNC_BATCH_SIZE, (currentBatch + 1)
|
||||
* SYNC_BATCH_SIZE));
|
||||
|
@ -714,6 +669,13 @@ public class RegistryFederationManager implements IRegistryFederationManager,
|
|||
}
|
||||
}
|
||||
|
||||
private void sendSyncMessage() {
|
||||
if (!SYNC_IN_PROGRESS.get()) {
|
||||
statusHandler.warn(SYNC_WARNING_MSG);
|
||||
monitorHandler.handle(Priority.WARN, SYNC_WARNING_MSG);
|
||||
}
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("isFederated")
|
||||
@Transactional
|
||||
|
@ -795,8 +757,8 @@ public class RegistryFederationManager implements IRegistryFederationManager,
|
|||
@GET
|
||||
@Path("subscribeToRegistry/{registryId}")
|
||||
@Transactional
|
||||
public void subscribeToRegistry(@PathParam("registryId") String registryId)
|
||||
throws Exception {
|
||||
public void subscribeToRegistry(@PathParam("registryId")
|
||||
String registryId) throws Exception {
|
||||
statusHandler.info("Establishing replication with [" + registryId
|
||||
+ "]...");
|
||||
RegistryType remoteRegistry = getRegistry(registryId);
|
||||
|
@ -809,8 +771,8 @@ public class RegistryFederationManager implements IRegistryFederationManager,
|
|||
@GET
|
||||
@Path("unsubscribeFromRegistry/{registryId}")
|
||||
@Transactional
|
||||
public void unsubscribeFromRegistry(
|
||||
@PathParam("registryId") String registryId) throws Exception {
|
||||
public void unsubscribeFromRegistry(@PathParam("registryId")
|
||||
String registryId) throws Exception {
|
||||
statusHandler.info("Disconnecting replication with [" + registryId
|
||||
+ "]...");
|
||||
RegistryType remoteRegistry = getRegistry(registryId);
|
||||
|
@ -824,8 +786,8 @@ public class RegistryFederationManager implements IRegistryFederationManager,
|
|||
@GET
|
||||
@Path("addReplicationServer/{registryId}")
|
||||
@Transactional
|
||||
public void addReplicationServer(@PathParam("registryId") String registryId)
|
||||
throws Exception {
|
||||
public void addReplicationServer(@PathParam("registryId")
|
||||
String registryId) throws Exception {
|
||||
getRegistry(registryId);
|
||||
servers.addReplicationServer(registryId);
|
||||
saveNotificationServers();
|
||||
|
@ -834,8 +796,8 @@ public class RegistryFederationManager implements IRegistryFederationManager,
|
|||
@GET
|
||||
@Path("removeReplicationServer/{registryId}")
|
||||
@Transactional
|
||||
public void removeReplicationServer(
|
||||
@PathParam("registryId") String registryId) throws Exception {
|
||||
public void removeReplicationServer(@PathParam("registryId")
|
||||
String registryId) throws Exception {
|
||||
getRegistry(registryId);
|
||||
servers.removeReplicationServer(registryId);
|
||||
saveNotificationServers();
|
||||
|
@ -978,7 +940,8 @@ public class RegistryFederationManager implements IRegistryFederationManager,
|
|||
}
|
||||
|
||||
public void processReplicationEvents() {
|
||||
if (federationEnabled && DbInit.isDbInitialized() && initialized.get()) {
|
||||
if (federationEnabled && DbInit.isDbInitialized() && initialized.get()
|
||||
&& !SYNC_IN_PROGRESS.get()) {
|
||||
if (!running.getAndSet(true)) {
|
||||
try {
|
||||
for (final String remoteRegistryId : servers
|
||||
|
@ -1029,7 +992,7 @@ public class RegistryFederationManager implements IRegistryFederationManager,
|
|||
.getBaseURL())) {
|
||||
|
||||
List<ReplicationEvent> events = replicationEventDao
|
||||
.getReplicationEvents(remoteRegistryId);
|
||||
.getReplicationEvents(remoteRegistryId, SYNC_BATCH_SIZE);
|
||||
|
||||
List<SimpleEntry<String, List<ReplicationEvent>>> orderedBatchedEvents = new ArrayList<SimpleEntry<String, List<ReplicationEvent>>>();
|
||||
SimpleEntry<String, List<ReplicationEvent>> lastEntry = null;
|
||||
|
@ -1135,7 +1098,14 @@ public class RegistryFederationManager implements IRegistryFederationManager,
|
|||
@Transactional
|
||||
public void updateUpTime() {
|
||||
if (initialized.get()) {
|
||||
federatedRegistryMonitor.updateTime();
|
||||
if (SYNC_NECESSARY) {
|
||||
if (!SYNC_IN_PROGRESS.get()
|
||||
&& TimeUtil.newGmtCalendar().get(Calendar.MINUTE) % 15 == 0) {
|
||||
sendSyncMessage();
|
||||
}
|
||||
} else {
|
||||
federatedRegistryMonitor.updateTime();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -65,11 +65,14 @@ public class RegistryAvailableRestService implements
|
|||
@GET
|
||||
@Produces("text/plain")
|
||||
public String isRegistryAvailable() {
|
||||
if (DbInit.isDbInitialized()
|
||||
&& RegistryFederationManager.initialized.get()) {
|
||||
return RegistryAvailability.AVAILABLE;
|
||||
} else {
|
||||
return RegistryAvailability.DB_NOT_INITIALIZED;
|
||||
if (DbInit.isDbInitialized()) {
|
||||
if (RegistryFederationManager.initialized.get()) {
|
||||
if(RegistryFederationManager.SYNC_IN_PROGRESS.get()){
|
||||
return RegistryAvailability.SYNC_IN_PROGRESS;
|
||||
}
|
||||
return RegistryAvailability.AVAILABLE;
|
||||
}
|
||||
}
|
||||
return RegistryAvailability.DB_NOT_INITIALIZED;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,4 +13,8 @@
|
|||
<bean factory-bean="eventBus" factory-method="register">
|
||||
<constructor-arg ref="AuditableEventService" />
|
||||
</bean>
|
||||
|
||||
<bean factory-bean="eventBus" factory-method="register">
|
||||
<constructor-arg ref="RegistryGarbageCollector" />
|
||||
</bean>
|
||||
</beans>
|
|
@ -36,6 +36,7 @@
|
|||
<bean id="RegistryGarbageCollector"
|
||||
class="com.raytheon.uf.edex.registry.ebxml.services.RegistryGarbageCollector">
|
||||
<constructor-arg ref="AuditableEventTypeDao" />
|
||||
<constructor-arg ref="slotTypeDao"/>
|
||||
</bean>
|
||||
|
||||
<bean id="objectReferenceResolver" class="com.raytheon.uf.edex.registry.ebxml.services.lifecycle.ObjectReferenceResolver">
|
||||
|
|
|
@ -28,7 +28,6 @@
|
|||
<bean id="registryObjectDao"
|
||||
class="com.raytheon.uf.edex.registry.ebxml.dao.RegistryObjectDao">
|
||||
<property name="sessionFactory" ref="metadataSessionFactory" />
|
||||
<property name="slotDao" ref="slotTypeDao" />
|
||||
</bean>
|
||||
|
||||
<bean id="registryDao" class="com.raytheon.uf.edex.registry.ebxml.dao.RegistryDao">
|
||||
|
|
|
@ -22,7 +22,6 @@ package com.raytheon.uf.edex.registry.ebxml.dao;
|
|||
import java.util.List;
|
||||
|
||||
import oasis.names.tc.ebxml.regrep.xsd.rim.v4.RegistryObjectType;
|
||||
import oasis.names.tc.ebxml.regrep.xsd.rim.v4.SlotType;
|
||||
|
||||
import org.springframework.transaction.annotation.Propagation;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
@ -45,6 +44,7 @@ import com.raytheon.uf.edex.registry.ebxml.exception.EbxmlRegistryException;
|
|||
* 7/29/2013 2191 bphillip Added new methods to support registry synchronization
|
||||
* 8/1/2013 1693 bphillip Added methods to facilitate implementation of the lifecyclemanager according to the 4.0 spec
|
||||
* 2/13/2014 2769 bphillip Added read only flags to query methods
|
||||
* 4/11/2014 3011 bphillip Changed merge to not delete unused slots
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -54,9 +54,6 @@ import com.raytheon.uf.edex.registry.ebxml.exception.EbxmlRegistryException;
|
|||
public class RegistryObjectDao extends
|
||||
RegistryObjectTypeDao<RegistryObjectType> {
|
||||
|
||||
/** Data access object for accessing slots */
|
||||
private SlotTypeDao slotDao;
|
||||
|
||||
/** Delete object type parameterized statement */
|
||||
private static final String GET_IDS_BY_OBJECT_TYPE = "SELECT regObj.id FROM RegistryObjectType regObj WHERE regObj.objectType=:objectType";
|
||||
|
||||
|
@ -85,10 +82,6 @@ public class RegistryObjectDao extends
|
|||
*/
|
||||
public void merge(RegistryObjectType newObject,
|
||||
RegistryObjectType existingObject) {
|
||||
// Delete the existing slot to prevent orphans
|
||||
for (SlotType slot : existingObject.getSlot()) {
|
||||
slotDao.delete(slot);
|
||||
}
|
||||
newObject.setId(existingObject.getId());
|
||||
template.merge(newObject);
|
||||
}
|
||||
|
@ -198,8 +191,4 @@ public class RegistryObjectDao extends
|
|||
return RegistryObjectType.class;
|
||||
}
|
||||
|
||||
public void setSlotDao(SlotTypeDao slotDao) {
|
||||
this.slotDao = slotDao;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -27,10 +27,15 @@ import oasis.names.tc.ebxml.regrep.xsd.rim.v4.AuditableEventType;
|
|||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import com.google.common.eventbus.Subscribe;
|
||||
import com.raytheon.uf.common.status.IUFStatusHandler;
|
||||
import com.raytheon.uf.common.status.UFStatus;
|
||||
import com.raytheon.uf.common.time.util.TimeUtil;
|
||||
import com.raytheon.uf.common.util.CollectionUtil;
|
||||
import com.raytheon.uf.edex.registry.ebxml.dao.AuditableEventTypeDao;
|
||||
import com.raytheon.uf.edex.registry.ebxml.dao.SlotTypeDao;
|
||||
import com.raytheon.uf.edex.registry.ebxml.exception.EbxmlRegistryException;
|
||||
import com.raytheon.uf.edex.registry.events.DeleteSlotEvent;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -49,6 +54,7 @@ import com.raytheon.uf.edex.registry.ebxml.exception.EbxmlRegistryException;
|
|||
* 1/15/2014 2613 bphillip Added Hibernate flush() call
|
||||
* 2/4/2014 2769 bphillip Removed flush and clear call
|
||||
* 2/13/2014 2769 bphillip Refactored to no longer use executor threads
|
||||
* 4/11/2014 3011 bphillip Added slot purging via event bus notifications
|
||||
* </pre>
|
||||
*
|
||||
* @author bphillip
|
||||
|
@ -68,6 +74,8 @@ public class RegistryGarbageCollector {
|
|||
/** Data access object for AuditableEventType */
|
||||
private AuditableEventTypeDao eventDao;
|
||||
|
||||
private SlotTypeDao slotDao;
|
||||
|
||||
/** The number of events to delete per batch */
|
||||
private static final int DELETE_BATCH_SIZE = 100;
|
||||
|
||||
|
@ -85,9 +93,11 @@ public class RegistryGarbageCollector {
|
|||
* @param eventDao
|
||||
* The auditable event dao to use
|
||||
*/
|
||||
public RegistryGarbageCollector(AuditableEventTypeDao eventDao) {
|
||||
public RegistryGarbageCollector(AuditableEventTypeDao eventDao,
|
||||
SlotTypeDao slotDao) {
|
||||
this();
|
||||
this.eventDao = eventDao;
|
||||
this.slotDao = slotDao;
|
||||
|
||||
}
|
||||
|
||||
|
@ -126,4 +136,18 @@ public class RegistryGarbageCollector {
|
|||
}
|
||||
} while (!expiredEvents.isEmpty());
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void deleteOrphanedSlot(DeleteSlotEvent slotEvent) {
|
||||
if (!CollectionUtil.isNullOrEmpty(slotEvent.getSlotsToDelete())) {
|
||||
long start = TimeUtil.currentTimeMillis();
|
||||
statusHandler.info("Deleting "
|
||||
+ slotEvent.getSlotsToDelete().size() + " slots...");
|
||||
slotDao.deleteAll(slotEvent.getSlotsToDelete());
|
||||
statusHandler.info("Deleted " + slotEvent.getSlotsToDelete().size()
|
||||
+ " slots in " + (TimeUtil.currentTimeMillis() - start)
|
||||
+ " ms");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -80,6 +80,7 @@ import com.raytheon.uf.edex.registry.ebxml.util.EbxmlExceptionUtil;
|
|||
import com.raytheon.uf.edex.registry.ebxml.util.EbxmlObjectUtil;
|
||||
import com.raytheon.uf.edex.registry.ebxml.util.xpath.RegistryXPathProcessor;
|
||||
import com.raytheon.uf.edex.registry.events.CreateAuditTrailEvent;
|
||||
import com.raytheon.uf.edex.registry.events.DeleteSlotEvent;
|
||||
|
||||
/**
|
||||
* The LifecycleManager interface allows a client to perform various lifecycle
|
||||
|
@ -108,7 +109,8 @@ import com.raytheon.uf.edex.registry.events.CreateAuditTrailEvent;
|
|||
* Separate update from create notifications.
|
||||
* 12/2/2013 1829 bphillip Auditable events are not genereted via messages on the event bus
|
||||
* 01/21/2014 2613 bphillip Removed verbose log message from removeObjects
|
||||
* 2/19/2014 2769 bphillip Added current time to audit trail events
|
||||
* 2/19/2014 2769 bphillip Added current time to audit trail events
|
||||
* 4/11/2014 3011 bphillip Modified merge behavior
|
||||
*
|
||||
*
|
||||
* </pre>
|
||||
|
@ -417,7 +419,7 @@ public class LifecycleManagerImpl implements LifecycleManager {
|
|||
*/
|
||||
checkReplica(request, obj, existingObject);
|
||||
objsUpdated.add(obj);
|
||||
registryObjectDao.merge(obj, existingObject);
|
||||
mergeObjects(obj, existingObject);
|
||||
statusHandler.info("Object [" + objectId
|
||||
+ "] replaced in the registry.");
|
||||
}
|
||||
|
@ -737,7 +739,7 @@ public class LifecycleManagerImpl implements LifecycleManager {
|
|||
+ "...");
|
||||
RegistryObjectType updatedObject = applyUpdates(objToUpdate,
|
||||
updateActions);
|
||||
registryObjectDao.merge(updatedObject, objToUpdate);
|
||||
mergeObjects(updatedObject, objToUpdate);
|
||||
}
|
||||
if (!objectsToUpdate.isEmpty()) {
|
||||
EventBus.publish(new CreateAuditTrailEvent(request.getId(),
|
||||
|
@ -752,6 +754,14 @@ public class LifecycleManagerImpl implements LifecycleManager {
|
|||
return response;
|
||||
}
|
||||
|
||||
private void mergeObjects(RegistryObjectType newObject,
|
||||
RegistryObjectType existingObject) {
|
||||
registryObjectDao.merge(newObject, existingObject);
|
||||
DeleteSlotEvent deleteSlotEvent = new DeleteSlotEvent(
|
||||
existingObject.getSlot());
|
||||
EventBus.publish(deleteSlotEvent);
|
||||
}
|
||||
|
||||
private RegistryObjectType applyUpdates(RegistryObjectType objectToUpdate,
|
||||
List<UpdateActionType> updateActions) throws MsgRegistryException {
|
||||
for (UpdateActionType updateAction : updateActions) {
|
||||
|
|
|
@ -0,0 +1,67 @@
|
|||
/**
|
||||
* 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.edex.registry.events;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import oasis.names.tc.ebxml.regrep.xsd.rim.v4.SlotType;
|
||||
|
||||
import com.raytheon.uf.common.event.Event;
|
||||
|
||||
/**
|
||||
* Event containing slots to be deleted by the registry garbage collector
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* 4/11/2014 3011 bphillip Initial Coding
|
||||
* </pre>
|
||||
*
|
||||
* @author bphillip
|
||||
* @version 1
|
||||
*/
|
||||
public class DeleteSlotEvent extends Event {
|
||||
|
||||
private static final long serialVersionUID = -2818002679753482984L;
|
||||
|
||||
private List<SlotType> slotsToDelete;
|
||||
|
||||
public DeleteSlotEvent(){
|
||||
super();
|
||||
}
|
||||
|
||||
public DeleteSlotEvent(List<SlotType> slotsToDelete){
|
||||
this.slotsToDelete = slotsToDelete;
|
||||
}
|
||||
|
||||
public List<SlotType> getSlotsToDelete() {
|
||||
return slotsToDelete;
|
||||
}
|
||||
|
||||
public void setSlotsToDelete(List<SlotType> slotsToDelete) {
|
||||
this.slotsToDelete = slotsToDelete;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -60,6 +60,7 @@ import com.raytheon.uf.edex.decodertools.time.TimeTools;
|
|||
* Sep 24, 2012 1210 jkorman Modified the decode method to create the
|
||||
* IDataRecord required by the SatelliteDao
|
||||
* Aug 30, 2013 2298 rjpeter Make getPluginName abstract
|
||||
* Apr 15, 2014 3017 bsteffen Call new methods in SatSpatialFactory
|
||||
* </pre>
|
||||
*
|
||||
* @author tk
|
||||
|
@ -273,49 +274,25 @@ public class RegionalSatDecoder extends AbstractDecoder {
|
|||
"Unable to decode Satellite: Encountered Unknown projection");
|
||||
} // end of if map projection block
|
||||
|
||||
SatMapCoverage mapCoverage = null;
|
||||
SatMapCoverage mapCoverage = SatSpatialFactory.getInstance()
|
||||
.getCoverageTwoCorners(mapProjection, nx, ny, lov, latin,
|
||||
la1, lo1, la2, lo2);
|
||||
|
||||
try {
|
||||
mapCoverage = SatSpatialFactory.getInstance()
|
||||
.getMapCoverage(mapProjection, nx, ny, dx, dy, lov,
|
||||
latin, la1, lo1, la2, lo2);
|
||||
} catch (Exception e) {
|
||||
StringBuffer buf = new StringBuffer();
|
||||
buf.append(
|
||||
"Error getting or constructing SatMapCoverage for values: ")
|
||||
.append("\n\t");
|
||||
buf.append("mapProjection=" + mapProjection).append("\n\t");
|
||||
buf.append("nx=" + nx).append("\n\t");
|
||||
buf.append("ny=" + ny).append("\n\t");
|
||||
buf.append("dx=" + dx).append("\n\t");
|
||||
buf.append("dy=" + dy).append("\n\t");
|
||||
buf.append("lov=" + lov).append("\n\t");
|
||||
buf.append("latin=" + latin).append("\n\t");
|
||||
buf.append("la1=" + la1).append("\n\t");
|
||||
buf.append("lo1=" + lo1).append("\n\t");
|
||||
buf.append("la2=" + la2).append("\n\t");
|
||||
buf.append("lo2=" + lo2).append("\n");
|
||||
throw new DecoderException(buf.toString(), e);
|
||||
} // end of catch block
|
||||
record.setTraceId(traceId);
|
||||
record.setCoverage(mapCoverage);
|
||||
record.setPersistenceTime(TimeTools.getSystemCalendar().getTime());
|
||||
|
||||
if (record != null) {
|
||||
record.setTraceId(traceId);
|
||||
record.setCoverage(mapCoverage);
|
||||
record.setPersistenceTime(TimeTools.getSystemCalendar()
|
||||
.getTime());
|
||||
// Set the data into the IDataRecord
|
||||
IDataRecord dataRec = SatelliteRecord.getDataRecord(record);
|
||||
if (dataRec != null) {
|
||||
record.setMessageData(dataRec);
|
||||
} else {
|
||||
handler.error(
|
||||
String.format("Could not create datarecord for %s"),
|
||||
traceId);
|
||||
record = null;
|
||||
}
|
||||
|
||||
// Set the data into the IDataRecord
|
||||
IDataRecord dataRec = SatelliteRecord.getDataRecord(record);
|
||||
if (dataRec != null) {
|
||||
record.setMessageData(dataRec);
|
||||
} else {
|
||||
handler.error(
|
||||
String.format("Could not create datarecord for %s"),
|
||||
traceId);
|
||||
record = null;
|
||||
}
|
||||
|
||||
} // end of if statement
|
||||
} // end of if data not empty statement
|
||||
|
||||
if (record == null) {
|
||||
|
|
Loading…
Add table
Reference in a new issue