From b234142252bf0373d497a92cb8b5983137048bbc Mon Sep 17 00:00:00 2001 From: Richard Peter Date: Thu, 24 Apr 2014 17:52:52 -0500 Subject: [PATCH] Issue #2726: Add hooks to stop archiving processes during shutdown. Change-Id: I16a219d8300eae431a8baaf27bcb00707908c67a Former-commit-id: 37342cba87edfa815891f8c6ea86b8dbb93628ff [formerly 37342cba87edfa815891f8c6ea86b8dbb93628ff [formerly 75ec73e02885fe0f646bc8961f3ea876597abab9]] Former-commit-id: 9a7e1aa9b0dbea63b66eac0d2b615d5057e7b8c2 Former-commit-id: caccf6ca52e725c09f1253f65f00259156be7988 --- .../META-INF/MANIFEST.MF | 2 +- .../META-INF/MANIFEST.MF | 2 +- .../META-INF/MANIFEST.MF | 2 +- cots/org.jep.win64/META-INF/MANIFEST.MF | 2 +- .../META-INF/MANIFEST.MF | 2 +- .../META-INF/MANIFEST.MF | 2 +- .../META-INF/MANIFEST.MF | 2 +- .../META-INF/MANIFEST.MF | 2 +- .../META-INF/MANIFEST.MF | 2 +- .../archive/DatabaseArchiveProcessor.java | 14 +- .../uf/edex/archive/DatabaseArchiver.java | 12 +- .../archive/purge/ArchivePurgeManager.java | 19 +- .../uf/edex/archive/purge/ArchivePurger.java | 49 ++--- .../META-INF/MANIFEST.MF | 2 +- .../feature.xml | 14 -- .../META-INF/MANIFEST.MF | 3 +- .../com/raytheon/uf/edex/core/EDEXUtil.java | 32 ++++ .../uf/edex/core/EdexTimerBasedThread.java | 20 ++- .../core/exception/ShutdownException.java | 71 ++++++++ .../uf/edex/database/dao/CoreDao.java | 37 ++-- .../processor/IDatabaseProcessor.java | 4 +- .../META-INF/MANIFEST.MF | 2 +- .../esb/camel/context/ContextManager.java | 168 +++++++----------- .../META-INF/MANIFEST.MF | 2 +- .../META-INF/MANIFEST.MF | 2 +- .../ModelSoundingPersistenceManager.java | 9 +- .../raytheon/uf/edex/stats/dao/StatsDao.java | 3 +- 27 files changed, 289 insertions(+), 192 deletions(-) create mode 100644 edexOsgi/com.raytheon.uf.edex.core/src/com/raytheon/uf/edex/core/exception/ShutdownException.java diff --git a/cave/com.raytheon.uf.viz.ccfp/META-INF/MANIFEST.MF b/cave/com.raytheon.uf.viz.ccfp/META-INF/MANIFEST.MF index fdcfff3df6..d43165c4b5 100644 --- a/cave/com.raytheon.uf.viz.ccfp/META-INF/MANIFEST.MF +++ b/cave/com.raytheon.uf.viz.ccfp/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: Ccfp Plug-in Bundle-SymbolicName: com.raytheon.uf.viz.ccfp;singleton:=true -Bundle-Version: 1.14.0 +Bundle-Version: 1.14.0.qualifier Bundle-Vendor: RAYTHEON Require-Bundle: com.raytheon.uf.viz.core Bundle-RequiredExecutionEnvironment: JavaSE-1.6 diff --git a/cave/com.raytheon.viz.aviation/META-INF/MANIFEST.MF b/cave/com.raytheon.viz.aviation/META-INF/MANIFEST.MF index a555b1bdeb..bf91f504a6 100644 --- a/cave/com.raytheon.viz.aviation/META-INF/MANIFEST.MF +++ b/cave/com.raytheon.viz.aviation/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: Aviation Plug-in Bundle-SymbolicName: com.raytheon.viz.aviation;singleton:=true -Bundle-Version: 1.14.0 +Bundle-Version: 1.14.0.qualifier Bundle-Activator: com.raytheon.viz.aviation.activator.Activator Bundle-Vendor: Raytheon Require-Bundle: org.eclipse.ui, diff --git a/cots/javax.media.opengl.win64/META-INF/MANIFEST.MF b/cots/javax.media.opengl.win64/META-INF/MANIFEST.MF index 13762725cb..14689af0b7 100644 --- a/cots/javax.media.opengl.win64/META-INF/MANIFEST.MF +++ b/cots/javax.media.opengl.win64/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: JOGL Win64 Specific Fragment Bundle-SymbolicName: javax.media.opengl.win64 -Bundle-Version: 1.14.0 +Bundle-Version: 1.14.0.qualifier Fragment-Host: javax.media.opengl;bundle-version="1.1.1" Bundle-RequiredExecutionEnvironment: JavaSE-1.6 Eclipse-PlatformFilter: (& (osgi.os=win32) (osgi.arch=x86_64)) diff --git a/cots/org.jep.win64/META-INF/MANIFEST.MF b/cots/org.jep.win64/META-INF/MANIFEST.MF index 9d6e46be92..e8e64d6361 100644 --- a/cots/org.jep.win64/META-INF/MANIFEST.MF +++ b/cots/org.jep.win64/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: Windows 64-bit Jep Library Bundle-SymbolicName: org.jep.win64 -Bundle-Version: 1.14.0 +Bundle-Version: 1.14.0.qualifier Fragment-Host: org.jep;bundle-version="2.3.0" Bundle-RequiredExecutionEnvironment: JavaSE-1.6 Eclipse-PlatformFilter: (& (osgi.os=win32) (osgi.arch=x86_64)) diff --git a/edexOsgi/com.raytheon.uf.common.dataplugin.ccfp/META-INF/MANIFEST.MF b/edexOsgi/com.raytheon.uf.common.dataplugin.ccfp/META-INF/MANIFEST.MF index 2ddf9956a1..7eab7f3790 100644 --- a/edexOsgi/com.raytheon.uf.common.dataplugin.ccfp/META-INF/MANIFEST.MF +++ b/edexOsgi/com.raytheon.uf.common.dataplugin.ccfp/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: CCFP common Plug-in Bundle-SymbolicName: com.raytheon.uf.common.dataplugin.ccfp -Bundle-Version: 1.14.0 +Bundle-Version: 1.14.0.qualifier Eclipse-RegisterBuddy: com.raytheon.uf.common.serialization Bundle-Vendor: RAYTHEON Bundle-RequiredExecutionEnvironment: JavaSE-1.6 diff --git a/edexOsgi/com.raytheon.uf.common.http/META-INF/MANIFEST.MF b/edexOsgi/com.raytheon.uf.common.http/META-INF/MANIFEST.MF index 3dcded65af..72c039815b 100644 --- a/edexOsgi/com.raytheon.uf.common.http/META-INF/MANIFEST.MF +++ b/edexOsgi/com.raytheon.uf.common.http/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: Common Http Bundle-SymbolicName: com.raytheon.uf.common.http -Bundle-Version: 1.14.0 +Bundle-Version: 1.14.0.qualifier Bundle-Vendor: RAYTHEON Bundle-RequiredExecutionEnvironment: JavaSE-1.6 Export-Package: com.raytheon.uf.common.http, diff --git a/edexOsgi/com.raytheon.uf.common.localization/META-INF/MANIFEST.MF b/edexOsgi/com.raytheon.uf.common.localization/META-INF/MANIFEST.MF index f0fbbca4ad..5f5fabcd45 100644 --- a/edexOsgi/com.raytheon.uf.common.localization/META-INF/MANIFEST.MF +++ b/edexOsgi/com.raytheon.uf.common.localization/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: Localization Plug-in Bundle-SymbolicName: com.raytheon.uf.common.localization -Bundle-Version: 1.14.0 +Bundle-Version: 1.14.0.qualifier Bundle-Vendor: Raytheon Require-Bundle: org.apache.commons.lang, com.raytheon.uf.common.serialization, diff --git a/edexOsgi/com.raytheon.uf.common.nc.bufr/META-INF/MANIFEST.MF b/edexOsgi/com.raytheon.uf.common.nc.bufr/META-INF/MANIFEST.MF index 231e4193a2..0a56fc8735 100644 --- a/edexOsgi/com.raytheon.uf.common.nc.bufr/META-INF/MANIFEST.MF +++ b/edexOsgi/com.raytheon.uf.common.nc.bufr/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: NetCDF Bufr Bundle-SymbolicName: com.raytheon.uf.common.nc.bufr -Bundle-Version: 1.14.0 +Bundle-Version: 1.14.0.qualifier Bundle-Vendor: RAYTHEON Bundle-RequiredExecutionEnvironment: JavaSE-1.6 Require-Bundle: ucar.nc2, diff --git a/edexOsgi/com.raytheon.uf.common.util/META-INF/MANIFEST.MF b/edexOsgi/com.raytheon.uf.common.util/META-INF/MANIFEST.MF index d82760aedd..2cabab5d90 100644 --- a/edexOsgi/com.raytheon.uf.common.util/META-INF/MANIFEST.MF +++ b/edexOsgi/com.raytheon.uf.common.util/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: Utility Plug-in Bundle-SymbolicName: com.raytheon.uf.common.util -Bundle-Version: 1.14.0 +Bundle-Version: 1.14.0.qualifier Bundle-Vendor: RAYTHEON Bundle-RequiredExecutionEnvironment: JavaSE-1.6 Require-Bundle: org.apache.commons.beanutils;bundle-version="1.8.3", diff --git a/edexOsgi/com.raytheon.uf.edex.archive/src/com/raytheon/uf/edex/archive/DatabaseArchiveProcessor.java b/edexOsgi/com.raytheon.uf.edex.archive/src/com/raytheon/uf/edex/archive/DatabaseArchiveProcessor.java index 646061083c..60d40d15e5 100644 --- a/edexOsgi/com.raytheon.uf.edex.archive/src/com/raytheon/uf/edex/archive/DatabaseArchiveProcessor.java +++ b/edexOsgi/com.raytheon.uf.edex.archive/src/com/raytheon/uf/edex/archive/DatabaseArchiveProcessor.java @@ -59,7 +59,9 @@ 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.common.util.FileUtil; +import com.raytheon.uf.edex.core.EDEXUtil; import com.raytheon.uf.edex.core.dataplugin.PluginRegistry; +import com.raytheon.uf.edex.core.exception.ShutdownException; import com.raytheon.uf.edex.database.plugin.PluginDao; import com.raytheon.uf.edex.database.processor.IDatabaseProcessor; @@ -78,6 +80,7 @@ import com.raytheon.uf.edex.database.processor.IDatabaseProcessor; * Jan 23, 2014 2555 rjpeter Updated to be a row at a time using ScrollableResults. * Feb 04, 2014 2770 rferrel The dumpPdos now dumps all PluginDataObjects. * Feb 12, 2014 2784 rjpeter Update logging for dup elim scenarios. + * Apr 23, 2014 2726 rjpeter Add shutdown checks to allow for timely shutdown. * * * @author rjpeter @@ -143,7 +146,7 @@ public class DatabaseArchiveProcessor> * .util.List) */ @Override - public boolean process(T object) { + public boolean process(T object) throws ShutdownException { if (object != null) { if (pdosByFile == null) { pdosByFile = new HashMap>>( @@ -191,7 +194,7 @@ public class DatabaseArchiveProcessor> * archives any associated hdf5 files. */ @Override - public void finish() { + public void finish() throws ShutdownException { if (entriesInMemory > 0) { try { savePdoMap(pdosByFile); @@ -228,6 +231,7 @@ public class DatabaseArchiveProcessor> } for (String dataStoreFile : datastoreFilesToArchive) { + EDEXUtil.checkShuttingDown(); IDataStore ds = DataStoreFactory.getDataStore(new File(FileUtil .join(pluginName, dataStoreFile))); // all dataStore files should end with .h5 @@ -346,12 +350,13 @@ public class DatabaseArchiveProcessor> * @throws IOException */ protected void savePdoMap(Map>> pdoMap) - throws SerializationException, IOException { + throws SerializationException, IOException, ShutdownException { StringBuilder baseDir = new StringBuilder(160); Set identifierSet = null; for (Map.Entry>> entry : pdoMap .entrySet()) { + EDEXUtil.checkShuttingDown(); baseDir.setLength(0); baseDir.append(archivePath).append(File.separator) .append(pluginName).append(File.separator) @@ -421,10 +426,11 @@ public class DatabaseArchiveProcessor> protected List> dupElimPreviousFiles( SortedMap fileMap, List> pdos, Set identifierSet) - throws IOException, SerializationException { + throws IOException, SerializationException, ShutdownException { if (!fileMap.isEmpty()) { Iterator fileIter = fileMap.values().iterator(); while (fileIter.hasNext()) { + EDEXUtil.checkShuttingDown(); File dataFile = fileIter.next(); int dupElimUntil = Integer.MAX_VALUE; FileStatus prevFileStatus = filesCreatedThisSession diff --git a/edexOsgi/com.raytheon.uf.edex.archive/src/com/raytheon/uf/edex/archive/DatabaseArchiver.java b/edexOsgi/com.raytheon.uf.edex.archive/src/com/raytheon/uf/edex/archive/DatabaseArchiver.java index 4f762aa9ff..a3facab329 100644 --- a/edexOsgi/com.raytheon.uf.edex.archive/src/com/raytheon/uf/edex/archive/DatabaseArchiver.java +++ b/edexOsgi/com.raytheon.uf.edex.archive/src/com/raytheon/uf/edex/archive/DatabaseArchiver.java @@ -38,6 +38,7 @@ 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.common.time.util.TimeUtil; +import com.raytheon.uf.edex.core.EDEXUtil; import com.raytheon.uf.edex.core.dataplugin.PluginRegistry; import com.raytheon.uf.edex.database.DataAccessLayerException; import com.raytheon.uf.edex.database.cluster.ClusterLockUtils; @@ -67,6 +68,7 @@ import com.raytheon.uf.edex.database.plugin.PluginFactory; * Dec 13, 2013 2555 rjpeter Refactored logic into DatabaseArchiveProcessor. * Feb 12, 2014 2784 rjpeter Fixed clusterLock to not update the time by default. * Apr 01, 2014 2862 rferrel Add exclusive lock at plug-in level. + * Apr 23, 2014 2726 rjpeter Added shutdown hook for quicker shutdown while archiver is running. * * * @author rjpeter @@ -92,7 +94,7 @@ public class DatabaseArchiver implements IPluginArchiver { private static final long MIN_DURATION_MILLIS = 30 * TimeUtil.MILLIS_PER_MINUTE; /** Maximum time increment to archive, note based off of insertTime. */ - private static final long MAX_DURATION_MILLIS = 120 * TimeUtil.MILLIS_PER_MINUTE; + private static final long MAX_DURATION_MILLIS = 60 * TimeUtil.MILLIS_PER_MINUTE; /** Default batch size for database queries */ private static final Integer defaultBatchSize = 10000; @@ -210,6 +212,10 @@ public class DatabaseArchiver implements IPluginArchiver { } public void archivePluginData(String pluginName, String archivePath) { + if (EDEXUtil.isShuttingDown()) { + return; + } + File archiveDir = new File(archivePath); File pluginDir = new File(archiveDir, pluginName); ClusterTask ctPlugin = getWriteLock(pluginDir.getAbsolutePath()); @@ -281,8 +287,8 @@ public class DatabaseArchiver implements IPluginArchiver { processor.setDebugArchiver(debugArchiver); processor.setBatchSize(batchSize.intValue()); - while ((startTime != null) && (endTime != null) - && !processor.isFailed()) { + while (!EDEXUtil.isShuttingDown() && (startTime != null) + && (endTime != null) && !processor.isFailed()) { statusHandler.info(pluginName + ": Checking for records from " + TimeUtil.formatDate(startTime) + " to " + TimeUtil.formatDate(endTime)); diff --git a/edexOsgi/com.raytheon.uf.edex.archive/src/com/raytheon/uf/edex/archive/purge/ArchivePurgeManager.java b/edexOsgi/com.raytheon.uf.edex.archive/src/com/raytheon/uf/edex/archive/purge/ArchivePurgeManager.java index a559eb5e37..1ff098d62d 100644 --- a/edexOsgi/com.raytheon.uf.edex.archive/src/com/raytheon/uf/edex/archive/purge/ArchivePurgeManager.java +++ b/edexOsgi/com.raytheon.uf.edex.archive/src/com/raytheon/uf/edex/archive/purge/ArchivePurgeManager.java @@ -43,6 +43,8 @@ import com.raytheon.uf.common.status.UFStatus; import com.raytheon.uf.common.status.UFStatus.Priority; import com.raytheon.uf.common.time.util.ITimer; import com.raytheon.uf.common.time.util.TimeUtil; +import com.raytheon.uf.edex.core.EDEXUtil; +import com.raytheon.uf.edex.core.exception.ShutdownException; import com.raytheon.uf.edex.database.cluster.ClusterLockUtils; import com.raytheon.uf.edex.database.cluster.ClusterLockUtils.LockState; import com.raytheon.uf.edex.database.cluster.ClusterTask; @@ -61,7 +63,7 @@ import com.raytheon.uf.edex.database.cluster.handler.SharedLockHandler.LockType; * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- * Apr 01, 2014 2862 rferrel Initial creation - * + * Apr 24, 2014 2726 rjpeter Added shutdown cancel * * * @author rferrel @@ -107,7 +109,8 @@ public class ArchivePurgeManager { * @param archive * @return purgeCount */ - public int purgeExpiredFromArchive(ArchiveConfig archive) { + public int purgeExpiredFromArchive(ArchiveConfig archive) + throws ShutdownException { String archiveRootDirPath = archive.getRootDir(); File archiveRootDir = new File(archiveRootDirPath); @@ -332,7 +335,9 @@ public class ArchivePurgeManager { private int purgeDir(File dir, IOFileFilter defaultTimeFilter, Calendar minPurgeTime, Calendar extPurgeTime, CategoryFileDateHelper helper, CategoryConfig category, - ClusterTask ct) { + ClusterTask ct) throws ShutdownException { + EDEXUtil.checkShuttingDown(); + int purgeCount = 0; File[] dirFiles = dir.listFiles(); @@ -342,6 +347,7 @@ public class ArchivePurgeManager { } for (File file : dirFiles) { + EDEXUtil.checkShuttingDown(); updateLockTime(ct); if (!file.isHidden()) { @@ -408,13 +414,18 @@ public class ArchivePurgeManager { * @param fileDataFilter * @return purgeCount */ - private int purgeDir(File dir, IOFileFilter fileDataFilter) { + private int purgeDir(File dir, IOFileFilter fileDataFilter) + throws ShutdownException { + EDEXUtil.checkShuttingDown(); + int purgeCount = 0; File[] dirFiles = dir.listFiles(); if (dirFiles == null) { sendPurgeMessage(); } else { for (File file : dirFiles) { + EDEXUtil.checkShuttingDown(); + if (!file.isHidden()) { if (file.isDirectory()) { purgeCount += purgeDir(file, fileDataFilter); diff --git a/edexOsgi/com.raytheon.uf.edex.archive/src/com/raytheon/uf/edex/archive/purge/ArchivePurger.java b/edexOsgi/com.raytheon.uf.edex.archive/src/com/raytheon/uf/edex/archive/purge/ArchivePurger.java index e011d6673f..4c022f3a4d 100644 --- a/edexOsgi/com.raytheon.uf.edex.archive/src/com/raytheon/uf/edex/archive/purge/ArchivePurger.java +++ b/edexOsgi/com.raytheon.uf.edex.archive/src/com/raytheon/uf/edex/archive/purge/ArchivePurger.java @@ -27,6 +27,7 @@ import com.raytheon.uf.common.status.UFStatus; import com.raytheon.uf.common.status.UFStatus.Priority; import com.raytheon.uf.common.time.util.ITimer; import com.raytheon.uf.common.time.util.TimeUtil; +import com.raytheon.uf.edex.core.exception.ShutdownException; /** * Purge task to purge archived data based on configured expiration. @@ -67,29 +68,37 @@ public class ArchivePurger { ITimer timer = TimeUtil.getTimer(); timer.start(); statusHandler.info("Archive Purge started."); - ArchivePurgeManager manager = ArchivePurgeManager.getInstance(); - manager.reset(); - Collection archives = manager.getArchives(); - for (ArchiveConfig archive : archives) { - ITimer archiveTimer = TimeUtil.getTimer(); - archiveTimer.start(); - int purgeCount = manager.purgeExpiredFromArchive(archive); - if (statusHandler.isPriorityEnabled(Priority.INFO)) { - StringBuilder sb = new StringBuilder(archive.getName()); - sb.append("::Archive Purged "); - sb.append(purgeCount); - sb.append(" file"); - if (purgeCount != 1) { - sb.append("s"); + try { + ArchivePurgeManager manager = ArchivePurgeManager.getInstance(); + manager.reset(); + Collection archives = manager.getArchives(); + for (ArchiveConfig archive : archives) { + ITimer archiveTimer = TimeUtil.getTimer(); + archiveTimer.start(); + int purgeCount = manager.purgeExpiredFromArchive(archive); + if (statusHandler.isPriorityEnabled(Priority.INFO)) { + StringBuilder sb = new StringBuilder(archive.getName()); + sb.append("::Archive Purged "); + sb.append(purgeCount); + sb.append(" file"); + if (purgeCount != 1) { + sb.append("s"); + } + sb.append(" in ") + .append(TimeUtil.prettyDuration(archiveTimer + .getElapsedTime())).append("."); + statusHandler.info(sb.toString()); } - sb.append(" in ") - .append(TimeUtil.prettyDuration(archiveTimer - .getElapsedTime())).append("."); - statusHandler.info(sb.toString()); } + + statusHandler.info("Archive Purge finished. Time to run: " + + TimeUtil.prettyDuration(timer.getElapsedTime())); + } catch (ShutdownException e) { + statusHandler + .info("Aborting Purge due to EDEX shutdown being initiated. Time to run: " + + TimeUtil.prettyDuration(timer + .getElapsedTime())); } - statusHandler.info("Archive Purge finished. Time to run: " - + TimeUtil.prettyDuration(timer.getElapsedTime())); } else { statusHandler.info("Archive Purge disabled, exiting"); } diff --git a/edexOsgi/com.raytheon.uf.edex.auth/META-INF/MANIFEST.MF b/edexOsgi/com.raytheon.uf.edex.auth/META-INF/MANIFEST.MF index d69c756259..23cb2c18dc 100644 --- a/edexOsgi/com.raytheon.uf.edex.auth/META-INF/MANIFEST.MF +++ b/edexOsgi/com.raytheon.uf.edex.auth/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: Auth Plug-in Bundle-SymbolicName: com.raytheon.uf.edex.auth -Bundle-Version: 1.14.0 +Bundle-Version: 1.14.0.qualifier Bundle-Vendor: RAYTHEON Bundle-RequiredExecutionEnvironment: JavaSE-1.6 Require-Bundle: com.raytheon.uf.common.serialization;bundle-version="1.11.31", diff --git a/edexOsgi/com.raytheon.uf.edex.common.core.feature/feature.xml b/edexOsgi/com.raytheon.uf.edex.common.core.feature/feature.xml index 394a231c84..32e469db17 100644 --- a/edexOsgi/com.raytheon.uf.edex.common.core.feature/feature.xml +++ b/edexOsgi/com.raytheon.uf.edex.common.core.feature/feature.xml @@ -84,20 +84,6 @@ version="0.0.0" unpack="false"/> - - - - + * + * SOFTWARE HISTORY + * + * Date Ticket# Engineer Description + * ------------ ---------- ----------- -------------------------- + * Apr 23, 2014 2726 rjpeter Initial creation + * + * + * + * @author rjpeter + * @version 1.0 + */ +public class ShutdownException extends EdexException { + + /** + * Default serial verion UID + */ + private static final long serialVersionUID = 1L; + + public ShutdownException() { + super("Aborting process, EDEX shutting down"); + } + + /** + * Create a Shutdown Exception instance from only a message + * + * @param message + */ + public ShutdownException(String message) { + super(message); + } + + /** + * Create a Shutdown Exception instance from both a message and a cause + * + * @param message + * @param cause + */ + public ShutdownException(String message, Throwable cause) { + super(message, cause); + } + +} diff --git a/edexOsgi/com.raytheon.uf.edex.database/src/com/raytheon/uf/edex/database/dao/CoreDao.java b/edexOsgi/com.raytheon.uf.edex.database/src/com/raytheon/uf/edex/database/dao/CoreDao.java index 9318c58209..943b272171 100644 --- a/edexOsgi/com.raytheon.uf.edex.database/src/com/raytheon/uf/edex/database/dao/CoreDao.java +++ b/edexOsgi/com.raytheon.uf.edex.database/src/com/raytheon/uf/edex/database/dao/CoreDao.java @@ -99,7 +99,8 @@ import com.raytheon.uf.edex.database.query.DatabaseQuery; * Apr 15, 2013 1868 bsteffen Rewrite mergeAll in PluginDao. * Nov 08, 2013 2361 njensen Changed method signature of saveOrUpdate to take Objects, not PersistableDataObjects * Dec 13, 2013 2555 rjpeter Added processByCriteria and fixed Generics warnings. - * Jan 23, 2014 2555 rjpeter Updated processByCriteriato be a row at a time using ScrollableResults. + * Jan 23, 2014 2555 rjpeter Updated processByCriteria to be a row at a time using ScrollableResults. + * Apr 23, 2014 2726 rjpeter Updated processByCriteria to throw exceptions back up to caller. * * * @author bphillip @@ -494,24 +495,34 @@ public class CoreDao extends HibernateDaoSupport { .scroll(ScrollMode.FORWARD_ONLY); boolean continueProcessing = true; - while (rs.next() && continueProcessing) { - Object[] row = rs.get(); - if (row.length > 0) { - continueProcessing = processor - .process((T) row[0]); - } - count++; - if ((count % batchSize) == 0) { - getSession().clear(); + try { + while (rs.next() && continueProcessing) { + Object[] row = rs.get(); + if (row.length > 0) { + continueProcessing = processor + .process((T) row[0]); + } + count++; + if ((count % batchSize) == 0) { + getSession().clear(); + } } + processor.finish(); + } catch (Exception e) { + /* + * Only way to propogate the error to the caller + * is to throw a runtime exception + */ + throw new RuntimeException( + "Error occurred during processing", e); } - processor.finish(); return count; } }); - } catch (TransactionException e) { - throw new DataAccessLayerException("Transaction failed", e); + } catch (Exception e) { + throw new DataAccessLayerException( + "Error occurred during processing", e); } return rowsProcessed; diff --git a/edexOsgi/com.raytheon.uf.edex.database/src/com/raytheon/uf/edex/database/processor/IDatabaseProcessor.java b/edexOsgi/com.raytheon.uf.edex.database/src/com/raytheon/uf/edex/database/processor/IDatabaseProcessor.java index 0a3a4e7e73..a0fa49ae20 100644 --- a/edexOsgi/com.raytheon.uf.edex.database/src/com/raytheon/uf/edex/database/processor/IDatabaseProcessor.java +++ b/edexOsgi/com.raytheon.uf.edex.database/src/com/raytheon/uf/edex/database/processor/IDatabaseProcessor.java @@ -44,12 +44,12 @@ public interface IDatabaseProcessor { * @param row * @return True if should continue processing, false otherwise. */ - public boolean process(T row); + public boolean process(T row) throws Exception; /** * Perform any post processing if necessary. */ - public void finish(); + public void finish() throws Exception; /** * Get the batch size of the query. diff --git a/edexOsgi/com.raytheon.uf.edex.esb.camel/META-INF/MANIFEST.MF b/edexOsgi/com.raytheon.uf.edex.esb.camel/META-INF/MANIFEST.MF index cf2c77856c..57d55f2f8b 100644 --- a/edexOsgi/com.raytheon.uf.edex.esb.camel/META-INF/MANIFEST.MF +++ b/edexOsgi/com.raytheon.uf.edex.esb.camel/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: Camel Plug-in Bundle-SymbolicName: com.raytheon.uf.edex.esb.camel -Bundle-Version: 1.14.0 +Bundle-Version: 1.14.0.qualifier Bundle-Vendor: Raytheon Bundle-RequiredExecutionEnvironment: JavaSE-1.6 Require-Bundle: org.apache.camel;bundle-version="1.0.0", diff --git a/edexOsgi/com.raytheon.uf.edex.esb.camel/src/com/raytheon/uf/edex/esb/camel/context/ContextManager.java b/edexOsgi/com.raytheon.uf.edex.esb.camel/src/com/raytheon/uf/edex/esb/camel/context/ContextManager.java index 231a546fda..7490a1e673 100644 --- a/edexOsgi/com.raytheon.uf.edex.esb.camel/src/com/raytheon/uf/edex/esb/camel/context/ContextManager.java +++ b/edexOsgi/com.raytheon.uf.edex.esb.camel/src/com/raytheon/uf/edex/esb/camel/context/ContextManager.java @@ -155,7 +155,7 @@ public class ContextManager implements ApplicationContextAware, .addAll(ContextDependencyMapping.DEPENDENCY_ENDPOINT_TYPES); internalEndpointTypes.add("timer"); internalEndpointTypes.add("quartz"); - internalEndpointTypes.add("clusteredquartz"); + internalEndpointTypes.add("direct"); } /** @@ -343,117 +343,18 @@ public class ContextManager implements ApplicationContextAware, .info("Spring Context not set. Start up never completed, cannot orderly shutdown"); } - statusHandler.info("Context Manager stopping routes"); + statusHandler.info("Context Manager stopping contexts"); try { - /* - * begin immediate shutdown of routes that are not an internal - * type - */ - LinkedList routesToStop = new LinkedList(); ContextData ctxData = getContextData(); List contexts = ctxData.getContexts(); List>> callbacks = new LinkedList>>(); for (final CamelContext context : contexts) { - /* - * group routes by context due to sync lock at context level - * for stopping a route - */ - List routes = context.getRoutes(); - if ((routes != null) && (routes.size() > 0)) { - for (Route route : routes) { - String uri = route.getEndpoint().getEndpointUri(); - Pair typeAndName = ContextData - .getEndpointTypeAndName(uri); - String type = typeAndName.getFirst(); - if (!internalEndpointTypes.contains(type)) { - routesToStop.add(route); - } - } - } - if (routesToStop.size() > 0) { - final IContextStateManager stateMgr = getStateManager(context); - final List tmp = routesToStop; - callbacks - .add(service - .submit(new Callable>() { - @Override - public Pair call() - throws Exception { - boolean rval = true; - for (Route route : tmp) { - try { - statusHandler.info("Stopping route [" - + route.getId() - + "]"); - rval &= stateMgr - .stopRoute(route); - } catch (Exception e) { - statusHandler.error( - "Error occurred closing route: " - + route.getId(), - e); - } - } - - return new Pair( - context, rval); - } - })); - routesToStop = new LinkedList(); - } + callbacks.add(service.submit(new StopContext(context))); } List failures = waitForCallbacks(callbacks, - "Waiting for external routes to shutdown: ", 1000); - - for (CamelContext failure : failures) { - statusHandler.error("Context [" + failure.getName() - + "] has routes that failed to stop"); - } - - statusHandler.info("Shutting down contexts"); - - for (final CamelContext context : contexts) { - final IContextStateManager stateManager = getStateManager(context); - if (stateManager.isContextStoppable(context)) { - callbacks - .add(service - .submit(new Callable>() { - @Override - public Pair call() - throws Exception { - boolean rval = false; - try { - statusHandler.info("Stopping context [" - + context.getName() - + "]"); - rval = stateManager - .stopContext(context); - - if (!rval) { - statusHandler.error("Context [" - + context - .getName() - + "] failed to stop"); - } - } catch (Throwable e) { - statusHandler.fatal( - "Error occurred stopping context: " - + context - .getName(), - e); - } - - return new Pair( - context, rval); - } - })); - } - } - - failures = waitForCallbacks(callbacks, "Waiting for contexts to shutdown: ", 1000); for (CamelContext failure : failures) { @@ -461,11 +362,72 @@ public class ContextManager implements ApplicationContextAware, + "] had a failure trying to stop"); } } catch (Throwable e) { - statusHandler.fatal("Error occurred during shutdown", e); + statusHandler.error("Error occurred during shutdown", e); } } } + /** + * Private Callable for stopping a context. If context not immediately + * stoppable will instead shutdown external routes first. + */ + private class StopContext implements Callable> { + final CamelContext context; + + private StopContext(CamelContext context) { + this.context = context; + } + + @Override + public Pair call() throws Exception { + boolean rval = false; + IContextStateManager stateManager = getStateManager(context); + + if (stateManager.isContextStoppable(context)) { + try { + statusHandler.info("Stopping context [" + context.getName() + + "]"); + rval = stateManager.stopContext(context); + + if (!rval) { + statusHandler.error("Context [" + context.getName() + + "] failed to stop"); + } + } catch (Throwable e) { + statusHandler.fatal("Error occurred stopping context: " + + context.getName(), e); + } + } else { + /* + * context not immediately stoppable, begin shutting down + * external routes instead + */ + List routes = context.getRoutes(); + rval = true; + + for (Route route : routes) { + String uri = route.getEndpoint().getEndpointUri(); + Pair typeAndName = ContextData + .getEndpointTypeAndName(uri); + String type = typeAndName.getFirst(); + if (!internalEndpointTypes.contains(type)) { + try { + statusHandler.info("Stopping route [" + + route.getId() + "]"); + rval &= stateManager.stopRoute(route); + } catch (Exception e) { + statusHandler.error( + "Error occurred Stopping route: " + + route.getId(), e); + } + } + } + } + + return new Pair(context, rval); + } + } + /** * Waits for all callbacks to finish printing a periodic message with number * of remaining callbacks. Returns a list of contexts that had a failure diff --git a/edexOsgi/com.raytheon.uf.edex.plugin.bufrobs/META-INF/MANIFEST.MF b/edexOsgi/com.raytheon.uf.edex.plugin.bufrobs/META-INF/MANIFEST.MF index 73325d4bbe..69f18f6d58 100644 --- a/edexOsgi/com.raytheon.uf.edex.plugin.bufrobs/META-INF/MANIFEST.MF +++ b/edexOsgi/com.raytheon.uf.edex.plugin.bufrobs/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: Bufrobs Bundle-SymbolicName: com.raytheon.uf.edex.plugin.bufrobs -Bundle-Version: 1.14.0 +Bundle-Version: 1.14.0.qualifier Bundle-Vendor: RAYTHEON Bundle-RequiredExecutionEnvironment: JavaSE-1.6 Require-Bundle: com.raytheon.uf.common.nc.bufr, diff --git a/edexOsgi/com.raytheon.uf.edex.plugin.ccfp/META-INF/MANIFEST.MF b/edexOsgi/com.raytheon.uf.edex.plugin.ccfp/META-INF/MANIFEST.MF index ea432442f1..c46bd23971 100644 --- a/edexOsgi/com.raytheon.uf.edex.plugin.ccfp/META-INF/MANIFEST.MF +++ b/edexOsgi/com.raytheon.uf.edex.plugin.ccfp/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: Ccfp Plug-in Bundle-SymbolicName: com.raytheon.uf.edex.plugin.ccfp -Bundle-Version: 1.14.0 +Bundle-Version: 1.14.0.qualifier Eclipse-RegisterBuddy: com.raytheon.uf.common.serialization, com.raytheon.edex.common Bundle-Vendor: RAYTHEON Require-Bundle: com.raytheon.edex.common, diff --git a/edexOsgi/com.raytheon.uf.edex.plugin.modelsounding/src/com/raytheon/uf/edex/plugin/modelsounding/ModelSoundingPersistenceManager.java b/edexOsgi/com.raytheon.uf.edex.plugin.modelsounding/src/com/raytheon/uf/edex/plugin/modelsounding/ModelSoundingPersistenceManager.java index d9a3fb6e27..d4a1554cd8 100644 --- a/edexOsgi/com.raytheon.uf.edex.plugin.modelsounding/src/com/raytheon/uf/edex/plugin/modelsounding/ModelSoundingPersistenceManager.java +++ b/edexOsgi/com.raytheon.uf.edex.plugin.modelsounding/src/com/raytheon/uf/edex/plugin/modelsounding/ModelSoundingPersistenceManager.java @@ -72,11 +72,13 @@ public class ModelSoundingPersistenceManager implements IContextStateProcessor { public void run() { run = true; - while (run) { + + // continue as long as there is data in the map + while (run || !containerMap.isEmpty()) { try { ModelSoundingStorageContainer container = null; synchronized (containerMap) { - while (containerMap.isEmpty() && run) { + while (run && containerMap.isEmpty()) { try { containerMap.wait(); } catch (InterruptedException e) { @@ -201,9 +203,8 @@ public class ModelSoundingPersistenceManager implements IContextStateProcessor { @Override public void preStop() { if (run) { - run = false; - synchronized (containerMap) { + run = false; containerMap.notifyAll(); while (!shutdown) { diff --git a/edexOsgi/com.raytheon.uf.edex.stats/src/com/raytheon/uf/edex/stats/dao/StatsDao.java b/edexOsgi/com.raytheon.uf.edex.stats/src/com/raytheon/uf/edex/stats/dao/StatsDao.java index 6965d305eb..ed506f2b06 100644 --- a/edexOsgi/com.raytheon.uf.edex.stats/src/com/raytheon/uf/edex/stats/dao/StatsDao.java +++ b/edexOsgi/com.raytheon.uf.edex.stats/src/com/raytheon/uf/edex/stats/dao/StatsDao.java @@ -117,8 +117,7 @@ public class StatsDao extends SessionManagedDao { sess = template.getSessionFactory().openStatelessSession(); // vacuum can't run within a transaction, hack to allow vacuum to // run from within hibernate - Query query = sess - .createSQLQuery("rollback; VACUUM ANALYZE events.stats"); + Query query = sess.createSQLQuery("rollback; VACUUM events.stats"); query.executeUpdate(); statusHandler.info("stats vacuumed"); } catch (Exception e) {