From 909571ebcac5ea8738ae979480f1413930cfed87 Mon Sep 17 00:00:00 2001 From: Richard Peter Date: Wed, 19 Mar 2014 14:23:52 -0500 Subject: [PATCH] Issue #2726: Edex graceful shutdown. Refactored to use inheritance and separate logic where possible. Addressed comments. Change-Id: I9e62414cd83121575bdf99a3b47466a7585bedb6 Former-commit-id: 17196b5dcd899885af39f0ce36091e10c4c23cc3 [formerly dbba727f3d97dedf782c75edd5e8c7f53ff03427 [formerly 6e015b3f61c20635077d6e8271e9b763e5a32fe1]] Former-commit-id: dbba727f3d97dedf782c75edd5e8c7f53ff03427 Former-commit-id: e4be1f24e721f5201aeed2b740b17d92e944b638 --- .../src/com/raytheon/uf/viz/core/VizApp.java | 15 +- .../esb/conf/res/base/attributeNames.xml | 1 - .../esb/conf/res/base/environment.xml | 1 - .../spring/32-bit/architecture.properties | 7 - .../spring/64-bit/architecture.properties | 7 - edexOsgi/build.edex/esb/conf/spring/edex.xml | 212 ++++--- edexOsgi/build.edex/esb/conf/wrapper.conf | 4 + edexOsgi/build.edex/esb/etc/default.sh | 2 - edexOsgi/build.edex/esb/etc/ingestDat.sh | 2 - edexOsgi/build.edex/esb/etc/ingestGrib.sh | 2 - edexOsgi/build.edex/esb/etc/request.sh | 2 - edexOsgi/build.edex/esb/etc/requestHydro.sh | 2 - .../res/spring/subscription-common.xml | 6 +- .../res/spring/subscription-request.xml | 10 +- .../res/spring/subscription-spring.xml | 4 +- .../raytheon/edex/plugin/InitializerBean.java | 72 --- .../res/spring/binlightning_ep-ingest.xml | 12 +- .../res/spring/bufrmos-ingest.xml | 8 +- .../res/spring/bufrua-ingest.xml | 8 +- .../res/spring/ccfp-ingest.xml | 7 +- .../build.properties | 3 +- .../res/spring/gfe-common.xml | 3 +- .../res/spring/gfe-request.xml | 27 +- .../res/spring/gfe-spring.xml | 34 +- .../com.raytheon.edex.plugin.gfe.properties | 2 + .../plugin/gfe/config/GFESiteActivation.java | 48 +- .../edex/plugin/gfe/isc/IscSendJob.java | 267 --------- .../edex/plugin/gfe/isc/SendIscSrv.java | 209 ++++++- .../edex/plugin/gfe/isc/SendIscSrvConfig.java | 82 --- .../plugin/gfe/smartinit/SmartInitSrv.java | 268 ++++----- .../gfe/smartinit/SmartInitSrvConfig.java | 91 --- .../res/spring/goessounding-ingest.xml | 9 +- .../res/spring/grib-decode.xml | 17 +- .../base/grib/thinnedModels/UkmetHR-NH.xml | 2 +- .../res/spring/ldadhydro-ingest.xml | 8 +- .../res/spring/ldadmanual-ingest.xml | 8 +- .../res/spring/ldadprofiler-ingest.xml | 8 +- .../res/spring/obs-ingest-decode.xml | 10 +- .../res/spring/obs-ingest-metarshef.xml | 9 +- .../res/spring/obs-ingest.xml | 3 +- .../res/spring/poessounding-ingest.xml | 8 +- .../res/spring/profiler-ingest.xml | 8 +- .../res/spring/radar-ingest.xml | 8 +- .../res/spring/recco-ingest.xml | 8 +- .../res/spring/redbook-ingest.xml | 17 +- .../res/spring/satellite-ingest.xml | 10 +- .../res/spring/sfcobs-ingest.xml | 8 +- .../res/spring/shef-ingest.xml | 11 +- .../res/spring/taf-ingest.xml | 8 +- .../res/spring/text-ingest.xml | 6 +- .../res/spring/textlightning_ep-ingest.xml | 8 +- .../res/spring/warning-ingest.xml | 8 +- .../res/spring/warning-request.xml | 48 +- .../GenerateGeospatialDataRequestHandler.java | 17 +- .../warning/gis/GeospatialDataGenerator.java | 135 +++-- .../warning/gis/GeospatialDataUpdater.java | 140 ----- .../res/spring/rpgenvdata-spring.xml | 2 +- .../res/spring/textdb-ingest.xml | 1 - .../res/spring/utility-request.xml | 2 +- .../META-INF/MANIFEST.MF | 1 - .../common/dataplugin/PluginProperties.java | 54 +- .../defaults/PluginPropertyDefaults.java | 120 ---- .../META-INF/MANIFEST.MF | 3 +- .../com/raytheon/uf/common/message/WsId.java | 84 +-- .../raytheon/uf/common/util/SystemUtil.java | 127 +++- .../res/spring/activetable-ingest.xml | 10 +- .../res/spring/activetable-request.xml | 5 +- .../com/raytheon/uf/edex/core/EDEXUtil.java | 49 +- .../uf/edex/core/EdexTimerBasedThread.java | 172 ++++++ .../uf/edex/core/IContextStateProcessor.java} | 50 +- .../edex/core/dataplugin/PluginRegistry.java | 34 +- .../res/spring/cpgsrv-spring.xml | 14 +- .../res/spring/database-common.xml | 4 +- .../edex/database/DatabasePluginRegistry.java | 33 +- .../edex/database/plugin/PluginFactory.java | 19 +- .../res/spring/event-datadelivery-ingest.xml | 7 +- .../res/spring/harvester-datadelivery.xml | 20 +- .../res/spring/registry-datadelivery.xml | 3 +- .../registry-federation-datadelivery.xml | 3 +- .../res/spring/grid-metadata.xml | 3 +- .../res/spring/dissemination-request.xml | 26 +- .../res/spring/distribution-spring.xml | 7 +- .../META-INF/MANIFEST.MF | 4 +- .../raytheon/uf/edex/esb/camel/Executor.java | 39 +- .../uf/edex/esb/camel/MessageProducer.java | 366 ++++++++---- .../uf/edex/esb/camel/StringToFile.java | 21 +- .../context/ClusteredContextManager.java | 190 ------ .../context/ClusteredContextStateManager.java | 144 +++++ .../edex/esb/camel/context/ContextData.java | 222 +++++++ .../context/ContextDependencyMapping.java | 268 +++++++++ .../esb/camel/context/ContextManager.java | 559 ++++++++++++++++-- .../context/DefaultContextStateManager.java | 215 +++++++ .../DependencyContextStateManager.java | 229 +++++++ .../esb/camel/context/DependencyNode.java | 145 +++++ .../camel/context/IContextStateManager.java | 96 +++ .../esb/camel/directvm/DirectVMComponent.java | 100 ---- .../esb/camel/directvm/DirectVMEndpoint.java | 102 ---- .../esb/camel/directvm/DirectVMProducer.java | 111 ---- .../jms/DedicatedThreadJmsComponent.java | 1 - .../spring/JmsThreadPoolTaskExecutor.java | 23 +- .../res/spring/persist-ingest.xml | 6 +- .../res/spring/persist-request.xml | 1 - .../ingest/notification/PluginNotifier.java | 27 +- .../res/spring/metartohmdb-plugin.xml | 7 +- .../res/spring/ndm-ingest.xml | 10 +- .../res/spring/ogc-common-convert.xml | 4 +- .../res/spring/ogc-common.xml | 4 +- .../res/spring/arealQpeGen-spring.xml | 6 +- .../res/spring/gaff-spring.xml | 8 +- .../res/spring/hpeDHRDecoder-spring.xml | 8 +- .../res/spring/mpeLightningSrv-ingest.xml | 2 +- .../res/spring/satpre-spring.xml | 6 +- .../res/spring/acars-ingest.xml | 10 +- .../res/spring/acarssounding-ingest.xml | 8 +- .../res/spring/bufrascat-ingest.xml | 8 +- .../res/spring/bufrhdw-ingest.xml | 8 +- .../res/spring/bufrmthdw-ingest.xml | 8 +- .../res/spring/bufrncwf-ingest.xml | 8 +- .../res/spring/bufrobs-ingest.xml | 7 +- .../res/spring/bufrquikscat-ingest.xml | 8 +- .../res/spring/bufrsigwx-ingest.xml | 8 +- .../res/spring/bufrssmi-ingest.xml | 8 +- .../res/spring/cwa-ingest.xml | 8 +- .../res/spring/cwat-ingest.xml | 2 +- .../res/spring/retrieval-common.xml | 3 +- .../res/spring/retrieval-ingest.xml | 3 +- .../res/spring/ffmp-ingest.xml | 2 +- .../res/spring/fog-ingest.xml | 2 +- .../res/spring/fssobs-ingest.xml | 2 +- .../res/spring/ldadmesonet-ingest.xml | 12 +- .../res/spring/lsr-ingest.xml | 8 +- .../res/spring/madis-ogc-routes.xml | 8 +- .../res/spring/madis-ogc.xml | 3 +- .../res/spring/madis-ogc-registry.xml | 8 +- .../res/spring/madis-common.xml | 3 +- .../res/spring/manualIngest-request.xml | 2 +- .../res/spring/manualIngest-spring.xml | 5 +- .../res/spring/modelsounding-ingest.xml | 28 +- .../modelsounding/ModelSoundingDecoder.java | 8 - .../ModelSoundingPersistenceManager.java | 85 ++- .../res/spring/crimss-ingest.xml | 8 +- .../res/spring/nucaps-ingest.xml | 8 +- .../res/spring/viirs-ingest.xml | 8 +- .../res/spring/obs-dpa-ingest.xml | 9 +- .../res/spring/obs-ogc-routes.xml | 8 +- .../res/spring/obs-ogc.xml | 5 +- .../res/spring/obs-ogc-registry.xml | 6 - .../res/spring/preciprate-ingest.xml | 2 +- .../res/spring/qc-ingest.xml | 8 +- .../res/spring/qpf-ingest.xml | 2 +- .../res/spring/satellite-mcidas-ingest.xml | 8 +- .../res/spring/scan-ingest.xml | 9 +- .../res/spring/svrwx-ingest.xml | 8 +- .../res/spring/tcg-ingest.xml | 8 +- .../res/spring/tcs-ingest.xml | 8 +- .../res/spring/vaa-ingest.xml | 8 +- .../res/spring/vil-ingest.xml | 2 +- .../res/spring/purge-spring.xml | 5 +- .../res/spring/ebxml-webserver.xml | 4 +- .../res/spring/site-common.xml | 8 +- .../res/spring/stats-ingest.xml | 7 +- .../res/spring/tafqueue-request.xml | 5 +- .../res/spring/textdbsrv-request.xml | 4 +- .../res/spring/wfs-ogc-soap-request.xml | 6 +- .../res/spring/ncinventory-request.xml | 28 +- .../spring/ncep-util-on-edex-ingestGrib.xml | 3 +- .../res/spring/ncep-util-on-edex-ingest.xml | 3 +- .../res/spring/airep-ingest.xml | 8 +- .../res/spring/airmet-ingest.xml | 8 +- .../res/spring/atcf-ingest.xml | 8 +- .../res/spring/aww-ingest.xml | 8 +- .../res/spring/convsigmet-ingest.xml | 8 +- .../res/spring/ffg-ingest.xml | 8 +- .../res/spring/geomag-common.xml | 6 +- .../res/spring/geomag-ingest.xml | 13 +- .../res/spring/gpd-common.xml | 3 +- .../res/spring/gpd-request.xml | 6 +- .../res/spring/idft-ingest.xml | 8 +- .../res/spring/intlsigmet-ingest.xml | 8 +- .../res/spring/mcidas-ingest.xml | 8 +- .../res/spring/mosaic-ingest.xml | 8 +- .../res/spring/ncgrib-file-endpoint.xml | 6 +- .../res/spring/ncpafm-ingest.xml | 8 +- .../res/spring/ncscat-ingest.xml | 8 +- .../res/spring/ncscd-ingest.xml | 7 +- .../res/spring/nctaf-ingest.xml | 8 +- .../res/spring/nctext-ingest.xml | 8 +- .../res/spring/ncuair-ingest.xml | 8 +- .../res/spring/nonconvsigmet-ingest.xml | 8 +- .../res/spring/ntrans-ingest.xml | 8 +- .../res/spring/pirep-ingest.xml | 8 +- .../res/spring/sgwh-ingest.xml | 8 +- .../res/spring/sgwhv-ingest.xml | 8 +- .../res/spring/solarimage-ingest.xml | 8 +- .../res/spring/ssha-ingest.xml | 8 +- .../res/spring/stormtrack-ingest.xml | 8 +- .../res/spring/tcm-ingest.xml | 8 +- .../res/spring/wcp-ingest.xml | 8 +- .../res/spring/regionalsat-ingest.xml | 8 +- tools/scripts/commit-msg | 0 tools/scripts/git-u-setup | 0 tools/scripts/uamend | 0 tools/scripts/ucommit | 0 tools/scripts/upull | 0 tools/scripts/upush | 0 tools/scripts/ustat | 0 206 files changed, 3562 insertions(+), 2865 deletions(-) delete mode 100644 edexOsgi/build.edex/esb/conf/spring/32-bit/architecture.properties delete mode 100644 edexOsgi/build.edex/esb/conf/spring/64-bit/architecture.properties delete mode 100644 edexOsgi/com.raytheon.edex.common/src/com/raytheon/edex/plugin/InitializerBean.java create mode 100644 edexOsgi/com.raytheon.edex.plugin.gfe/resources/com.raytheon.edex.plugin.gfe.properties delete mode 100644 edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/isc/IscSendJob.java delete mode 100644 edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/isc/SendIscSrvConfig.java delete mode 100644 edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/smartinit/SmartInitSrvConfig.java delete mode 100644 edexOsgi/com.raytheon.edex.plugin.warning/src/com/raytheon/edex/plugin/warning/gis/GeospatialDataUpdater.java delete mode 100644 edexOsgi/com.raytheon.uf.common.dataplugin/src/com/raytheon/uf/common/dataplugin/defaults/PluginPropertyDefaults.java create mode 100644 edexOsgi/com.raytheon.uf.edex.core/src/com/raytheon/uf/edex/core/EdexTimerBasedThread.java rename edexOsgi/{com.raytheon.edex.plugin.warning/src/com/raytheon/edex/plugin/warning/gis/GeospatialDataGeneratorThread.java => com.raytheon.uf.edex.core/src/com/raytheon/uf/edex/core/IContextStateProcessor.java} (53%) delete mode 100644 edexOsgi/com.raytheon.uf.edex.esb.camel/src/com/raytheon/uf/edex/esb/camel/context/ClusteredContextManager.java create mode 100644 edexOsgi/com.raytheon.uf.edex.esb.camel/src/com/raytheon/uf/edex/esb/camel/context/ClusteredContextStateManager.java create mode 100644 edexOsgi/com.raytheon.uf.edex.esb.camel/src/com/raytheon/uf/edex/esb/camel/context/ContextData.java create mode 100644 edexOsgi/com.raytheon.uf.edex.esb.camel/src/com/raytheon/uf/edex/esb/camel/context/ContextDependencyMapping.java create mode 100644 edexOsgi/com.raytheon.uf.edex.esb.camel/src/com/raytheon/uf/edex/esb/camel/context/DefaultContextStateManager.java create mode 100644 edexOsgi/com.raytheon.uf.edex.esb.camel/src/com/raytheon/uf/edex/esb/camel/context/DependencyContextStateManager.java create mode 100644 edexOsgi/com.raytheon.uf.edex.esb.camel/src/com/raytheon/uf/edex/esb/camel/context/DependencyNode.java create mode 100644 edexOsgi/com.raytheon.uf.edex.esb.camel/src/com/raytheon/uf/edex/esb/camel/context/IContextStateManager.java delete mode 100644 edexOsgi/com.raytheon.uf.edex.esb.camel/src/com/raytheon/uf/edex/esb/camel/directvm/DirectVMComponent.java delete mode 100644 edexOsgi/com.raytheon.uf.edex.esb.camel/src/com/raytheon/uf/edex/esb/camel/directvm/DirectVMEndpoint.java delete mode 100644 edexOsgi/com.raytheon.uf.edex.esb.camel/src/com/raytheon/uf/edex/esb/camel/directvm/DirectVMProducer.java mode change 100644 => 100755 tools/scripts/commit-msg mode change 100644 => 100755 tools/scripts/git-u-setup mode change 100644 => 100755 tools/scripts/uamend mode change 100644 => 100755 tools/scripts/ucommit mode change 100644 => 100755 tools/scripts/upull mode change 100644 => 100755 tools/scripts/upush mode change 100644 => 100755 tools/scripts/ustat diff --git a/cave/com.raytheon.uf.viz.core/src/com/raytheon/uf/viz/core/VizApp.java b/cave/com.raytheon.uf.viz.core/src/com/raytheon/uf/viz/core/VizApp.java index 40bd59022a..a10b88e1df 100644 --- a/cave/com.raytheon.uf.viz.core/src/com/raytheon/uf/viz/core/VizApp.java +++ b/cave/com.raytheon.uf.viz.core/src/com/raytheon/uf/viz/core/VizApp.java @@ -31,6 +31,7 @@ import org.eclipse.ui.statushandlers.StatusManager; import com.raytheon.uf.common.localization.LocalizationContext.LocalizationLevel; import com.raytheon.uf.common.message.WsId; +import com.raytheon.uf.common.util.SystemUtil; import com.raytheon.uf.viz.core.localization.LocalizationManager; /** @@ -49,7 +50,7 @@ import com.raytheon.uf.viz.core.localization.LocalizationManager; * Aug 27, 2013 2295 bkowal Removed the jms server property; added * jms connection string * Feb 17, 2014 2812 njensen getHostName() now uses getWsId()'s hostname - * + * Mar 20, 2014 2726 rjpeter Moved host processing to SystemUtil. * * * @author chammack @@ -252,21 +253,13 @@ public final class VizApp { private static String host = null; /** - * Gets the host name from the WsId of the host machine calling the function + * Gets the host name of the machine calling the function * * @return */ public static synchronized String getHostName() { if (host == null) { - host = getWsId().getHostName(); - if (host == null) { - String hostname = System.getenv("HOSTNAME"); - if (hostname != null && hostname.trim().length() > 0) { - host = hostname; - } else { - host = "localhost"; - } - } + host = SystemUtil.getHostName(); } return host; } diff --git a/edexOsgi/build.edex/esb/conf/res/base/attributeNames.xml b/edexOsgi/build.edex/esb/conf/res/base/attributeNames.xml index c6e6cd6568..6566c0bfd5 100644 --- a/edexOsgi/build.edex/esb/conf/res/base/attributeNames.xml +++ b/edexOsgi/build.edex/esb/conf/res/base/attributeNames.xml @@ -233,7 +233,6 @@ utilityDir staticDir sitename - gfeSmartInitEnable logDir fxaDebugSaveBadTextFiles archiveDir diff --git a/edexOsgi/build.edex/esb/conf/res/base/environment.xml b/edexOsgi/build.edex/esb/conf/res/base/environment.xml index f76a4ebefe..d86d21241a 100644 --- a/edexOsgi/build.edex/esb/conf/res/base/environment.xml +++ b/edexOsgi/build.edex/esb/conf/res/base/environment.xml @@ -48,7 +48,6 @@ ${env:edex.home}/data/share ${env:edex.home}/data/utility ${env:edex.home}/data/static - true false ${env:edex.home}/../GFESuite/ /data/fxa/mhs diff --git a/edexOsgi/build.edex/esb/conf/spring/32-bit/architecture.properties b/edexOsgi/build.edex/esb/conf/spring/32-bit/architecture.properties deleted file mode 100644 index ce5c79eac6..0000000000 --- a/edexOsgi/build.edex/esb/conf/spring/32-bit/architecture.properties +++ /dev/null @@ -1,7 +0,0 @@ -# The following properties are used to define the EDEX system configuration. -# Modifying these values will affect system performance. - -smartinit.threadpoolsize=3 -# smartinit.threads should be 2 less than smartinit.threadpoolszie -# to account for reading from the notify topic and the manual queue -smartinit.threads=1 diff --git a/edexOsgi/build.edex/esb/conf/spring/64-bit/architecture.properties b/edexOsgi/build.edex/esb/conf/spring/64-bit/architecture.properties deleted file mode 100644 index dd5c190435..0000000000 --- a/edexOsgi/build.edex/esb/conf/spring/64-bit/architecture.properties +++ /dev/null @@ -1,7 +0,0 @@ -# The following properties are used to define the EDEX system configuration. -# Modifying these values will affect system performance. - -smartinit.threadpoolsize=4 -# smartinit.threads should be 2 less than smartinit.threadpoolszie -# to account for reading from the notify topic and the manual queue -smartinit.threads=2 diff --git a/edexOsgi/build.edex/esb/conf/spring/edex.xml b/edexOsgi/build.edex/esb/conf/spring/edex.xml index fd937b7deb..457fbdef65 100644 --- a/edexOsgi/build.edex/esb/conf/spring/edex.xml +++ b/edexOsgi/build.edex/esb/conf/spring/edex.xml @@ -3,14 +3,14 @@ xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:util="http://www.springframework.org/schema/util" - xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd + xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.1.xsd"> - - - - + + + + @@ -24,7 +24,7 @@ - + @@ -64,12 +64,14 @@ - + + + - + - + - - - + + + - + - + - + - + - - + @@ -136,53 +137,84 @@ - + - - - - + + + + - - + + + + + + - + + + + + + + + + + + + + + + + + + + + + + - - - - - - - + + + + + + + - - - - - + + + + + + + + + + - - - - - - - - - - - + - - + + - + @@ -193,38 +225,10 @@ - + - - - - - - - - - - - - - - - - - - - - - - + class="com.raytheon.uf.edex.esb.camel.EDEXParameterMappingStrategy" /> @@ -248,7 +252,7 @@ - + @@ -263,13 +267,6 @@ - - - - - - - @@ -281,16 +278,15 @@ - + + errorHandlerRef="errorHandler"> - + java.lang.Throwable @@ -298,10 +294,6 @@ - - - @@ -314,7 +306,6 @@ file:${edex.home}/conf/spring/cron.properties - file:${edex.home}/conf/spring/${edex.arch}/architecture.properties @@ -322,11 +313,11 @@ - + - + @@ -341,7 +332,7 @@ - + @@ -353,14 +344,10 @@ - - - - + Single scheduler used by all endpoints so there is only one threadpool. + Thread pool configured in edex/config/resources/quartz.properties. + Requires work around in ContextManager.postProcessBeanFactory when JMX is disabled --> @@ -376,5 +363,4 @@ class="com.raytheon.uf.edex.esb.camel.cluster.quartz.ClusteredQuartzComponent"> - diff --git a/edexOsgi/build.edex/esb/conf/wrapper.conf b/edexOsgi/build.edex/esb/conf/wrapper.conf index f9a378082f..a42d5cf480 100644 --- a/edexOsgi/build.edex/esb/conf/wrapper.conf +++ b/edexOsgi/build.edex/esb/conf/wrapper.conf @@ -160,6 +160,10 @@ wrapper.app.parameter.2=start wrapper.ping.timeout=300 +# jvm will be hard killed after 5 minutes of trying to shutdown +wrapper.jvm_exit.timeout=0 +wrapper.shutdown.timeout=300 + #******************************************************************** # Monitor the Application #******************************************************************** diff --git a/edexOsgi/build.edex/esb/etc/default.sh b/edexOsgi/build.edex/esb/etc/default.sh index 7d2a181151..a9c35fdd80 100644 --- a/edexOsgi/build.edex/esb/etc/default.sh +++ b/edexOsgi/build.edex/esb/etc/default.sh @@ -23,8 +23,6 @@ export MAX_MEM=1300 # in Meg export MAX_PERM_SIZE=128m export EDEX_JMX_PORT=1616 export EDEX_DEBUG_PORT=5005 -export JMS_POOL_MIN=64 -export JMS_POOL_MAX=128 export METADATA_POOL_MIN=5 export METADATA_POOL_MAX=50 export METADATA_POOL_TIMEOUT=300 diff --git a/edexOsgi/build.edex/esb/etc/ingestDat.sh b/edexOsgi/build.edex/esb/etc/ingestDat.sh index 473b30db5d..2c551e3f81 100644 --- a/edexOsgi/build.edex/esb/etc/ingestDat.sh +++ b/edexOsgi/build.edex/esb/etc/ingestDat.sh @@ -21,8 +21,6 @@ export INIT_MEM=256 # in Meg export MAX_MEM=1792 # in Meg -export JMS_POOL_MIN=16 -export JMS_POOL_MAX=32 export METADATA_POOL_MIN=15 export METADATA_POOL_MAX=30 export EDEX_DEBUG_PORT=5008 diff --git a/edexOsgi/build.edex/esb/etc/ingestGrib.sh b/edexOsgi/build.edex/esb/etc/ingestGrib.sh index 971f85c6fd..0c424d1638 100644 --- a/edexOsgi/build.edex/esb/etc/ingestGrib.sh +++ b/edexOsgi/build.edex/esb/etc/ingestGrib.sh @@ -21,8 +21,6 @@ export INIT_MEM=128 # in Meg export MAX_MEM=512 # in Meg -export JMS_POOL_MIN=4 -export JMS_POOL_MAX=16 export METADATA_POOL_MIN=4 export METADATA_POOL_MAX=10 export EDEX_DEBUG_PORT=5007 diff --git a/edexOsgi/build.edex/esb/etc/request.sh b/edexOsgi/build.edex/esb/etc/request.sh index 4a7303b979..536081a2f2 100644 --- a/edexOsgi/build.edex/esb/etc/request.sh +++ b/edexOsgi/build.edex/esb/etc/request.sh @@ -29,8 +29,6 @@ export SERIALIZE_STREAM_INIT_SIZE_MB=2 export SERIALIZE_STREAM_MAX_SIZE_MB=8 -export JMS_POOL_MIN=16 -export JMS_POOL_MAX=32 export EDEX_DEBUG_PORT=5005 export EDEX_JMX_PORT=1616 export MGMT_PORT=9601 diff --git a/edexOsgi/build.edex/esb/etc/requestHydro.sh b/edexOsgi/build.edex/esb/etc/requestHydro.sh index 4d07d95073..37e80657b7 100644 --- a/edexOsgi/build.edex/esb/etc/requestHydro.sh +++ b/edexOsgi/build.edex/esb/etc/requestHydro.sh @@ -29,8 +29,6 @@ export SERIALIZE_STREAM_INIT_SIZE_MB=2 export SERIALIZE_STREAM_MAX_SIZE_MB=8 -export JMS_POOL_MIN=8 -export JMS_POOL_MAX=24 export EDEX_DEBUG_PORT=5005 export EDEX_JMX_PORT=1616 export MGMT_PORT=9601 diff --git a/edexOsgi/com.raytheon.edex.autobldsrv/res/spring/subscription-common.xml b/edexOsgi/com.raytheon.edex.autobldsrv/res/spring/subscription-common.xml index 766bbba845..24d5dc5b41 100644 --- a/edexOsgi/com.raytheon.edex.autobldsrv/res/spring/subscription-common.xml +++ b/edexOsgi/com.raytheon.edex.autobldsrv/res/spring/subscription-common.xml @@ -20,8 +20,8 @@ depends-on="metadataTxManager"> - - + @@ -34,7 +34,7 @@ - + diff --git a/edexOsgi/com.raytheon.edex.autobldsrv/res/spring/subscription-request.xml b/edexOsgi/com.raytheon.edex.autobldsrv/res/spring/subscription-request.xml index 789fd319d9..c40e01ac60 100644 --- a/edexOsgi/com.raytheon.edex.autobldsrv/res/spring/subscription-request.xml +++ b/edexOsgi/com.raytheon.edex.autobldsrv/res/spring/subscription-request.xml @@ -5,13 +5,13 @@ http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd"> - - - + uri="jetty:http://0.0.0.0:${HTTP_PORT}/services/subscribe?disableStreamCache=true" /> + + diff --git a/edexOsgi/com.raytheon.edex.autobldsrv/res/spring/subscription-spring.xml b/edexOsgi/com.raytheon.edex.autobldsrv/res/spring/subscription-spring.xml index cdf139c5bf..9674008e75 100644 --- a/edexOsgi/com.raytheon.edex.autobldsrv/res/spring/subscription-spring.xml +++ b/edexOsgi/com.raytheon.edex.autobldsrv/res/spring/subscription-spring.xml @@ -8,14 +8,14 @@ - + - diff --git a/edexOsgi/com.raytheon.edex.common/src/com/raytheon/edex/plugin/InitializerBean.java b/edexOsgi/com.raytheon.edex.common/src/com/raytheon/edex/plugin/InitializerBean.java deleted file mode 100644 index 6e8de257ad..0000000000 --- a/edexOsgi/com.raytheon.edex.common/src/com/raytheon/edex/plugin/InitializerBean.java +++ /dev/null @@ -1,72 +0,0 @@ -/** - * This software was developed and / or modified by Raytheon Company, - * pursuant to Contract DG133W-05-CQ-1067 with the US Government. - * - * U.S. EXPORT CONTROLLED TECHNICAL DATA - * This software product contains export-restricted data whose - * export/transfer/disclosure is restricted by U.S. law. Dissemination - * to non-U.S. persons whether in the United States or abroad requires - * an export license or other authorization. - * - * Contractor Name: Raytheon Company - * Contractor Address: 6825 Pine Street, Suite 340 - * Mail Stop B8 - * Omaha, NE 68106 - * 402.291.0100 - * - * See the AWIPS II Master Rights File ("Master Rights File.pdf") for - * further licensing information. - **/ - -package com.raytheon.edex.plugin; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * This class is instantiated on startup by the ESB spring container context - * before any other beans. Therefore, any system level initialization activities - * may be placed here. - *

- * The basic functionality of this class will initialize all the plugins - * - *

- * SOFTWARE HISTORY
- * Date         Ticket#    Engineer    Description
- * ------------ ---------- ----------- --------------------------
- * 02/06/09     1990       bphillip    Initial creation
- * 
- * - * @author bphillip - * @version 1.0 - */ -public class InitializerBean { - - /** The logger */ - protected transient Log logger = LogFactory.getLog(getClass()); - - /** - * Creates a new Initializer bean - *

- * This bean should never be explicitly instantiated - */ - public InitializerBean() { - // Check to see if the plugin version table exists. If not, the schema - // needs to be exported to the database - /* - * pvd = new PluginVersionDao(); if (!pvd.isDbInitialized()) { - * logger.warn("Databases have not been initialized..."); - * logger.info("Initializing Databases..."); - * logger.info("Exporting common table ddls..."); - * SchemaManager.getInstance().createCommonTables(); - * logger.info("Running setup scripts..."); try { - * SchemaManager.getInstance().runCommonScripts(); } catch - * (PluginException e) { logger.fatal("ERROR RUNNING COMMON SCRIPTS!", - * e); } - * - * } - */ - logger.info("Database initialization complete!"); - } - -} diff --git a/edexOsgi/com.raytheon.edex.plugin.binlightning/res/spring/binlightning_ep-ingest.xml b/edexOsgi/com.raytheon.edex.plugin.binlightning/res/spring/binlightning_ep-ingest.xml index 4c60b738c3..d8a0ea3c5f 100644 --- a/edexOsgi/com.raytheon.edex.plugin.binlightning/res/spring/binlightning_ep-ingest.xml +++ b/edexOsgi/com.raytheon.edex.plugin.binlightning/res/spring/binlightning_ep-ingest.xml @@ -4,7 +4,7 @@ http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd"> + class="com.raytheon.edex.plugin.binlightning.BinLightningDecoder" /> @@ -12,16 +12,14 @@ - + - + - - - - - - - - - + - - + + + + @@ -420,6 +415,7 @@ + @@ -488,11 +484,16 @@ + + + + + + - + @@ -512,7 +513,7 @@ - + diff --git a/edexOsgi/com.raytheon.edex.plugin.gfe/res/spring/gfe-spring.xml b/edexOsgi/com.raytheon.edex.plugin.gfe/res/spring/gfe-spring.xml index 64d9cced5c..c41d88919f 100644 --- a/edexOsgi/com.raytheon.edex.plugin.gfe/res/spring/gfe-spring.xml +++ b/edexOsgi/com.raytheon.edex.plugin.gfe/res/spring/gfe-spring.xml @@ -4,24 +4,20 @@ http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd"> - - - + + + - - - + + - - - - - - + + + @@ -29,8 +25,10 @@ - + + + @@ -72,6 +70,12 @@ + + + + + + + errorHandlerRef="errorHandler"> @@ -134,7 +138,7 @@ - + diff --git a/edexOsgi/com.raytheon.edex.plugin.gfe/resources/com.raytheon.edex.plugin.gfe.properties b/edexOsgi/com.raytheon.edex.plugin.gfe/resources/com.raytheon.edex.plugin.gfe.properties new file mode 100644 index 0000000000..a5529c1a1c --- /dev/null +++ b/edexOsgi/com.raytheon.edex.plugin.gfe/resources/com.raytheon.edex.plugin.gfe.properties @@ -0,0 +1,2 @@ +# The number of smart init threads to use +smartinit.threads=2 diff --git a/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/config/GFESiteActivation.java b/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/config/GFESiteActivation.java index 0f6e90ccdc..938f49ac8f 100644 --- a/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/config/GFESiteActivation.java +++ b/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/config/GFESiteActivation.java @@ -59,20 +59,21 @@ import com.raytheon.uf.edex.site.notify.SendSiteActivationNotifications; * SOFTWARE HISTORY * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- - * Jul 9, 2009 njensen Initial creation - * Oct 26, 2010 #6811 jclark changed listener type - * Apr 06, 2012 #457 dgilling Clear site's ISCSendRecords on - * site deactivation. - * Jul 12, 2012 15162 ryu added check for invalid db at activation - * Dec 11, 2012 14360 ryu log a clean message in case of - * missing configuration (no stack trace). - * Feb 15, 2013 1638 mschenke Moved sending of site notification messages to edex plugin - * Feb 28, 2013 #1447 dgilling Enable active table fetching on site - * activation. - * Mar 20, 2013 #1774 randerso Changed to use GFED2DDao - * May 02, 2013 #1969 randerso Moved updateDbs method into IFPGridDatabase - * Jun 13, 2013 #2044 randerso Refactored to use IFPServer - * Oct 16, 2013 #2475 dgilling Better error handling for IRT activation. + * Jul 9, 2009 njensen Initial creation + * Oct 26, 2010 #6811 jclark changed listener type + * Apr 06, 2012 #457 dgilling Clear site's ISCSendRecords on + * site deactivation. + * Jul 12, 2012 15162 ryu added check for invalid db at activation + * Dec 11, 2012 14360 ryu log a clean message in case of + * missing configuration (no stack trace). + * Feb 15, 2013 1638 mschenke Moved sending of site notification messages to edex plugin + * Feb 28, 2013 #1447 dgilling Enable active table fetching on site + * activation. + * Mar 20, 2013 #1774 randerso Changed to use GFED2DDao + * May 02, 2013 #1969 randerso Moved updateDbs method into IFPGridDatabase + * Jun 13, 2013 #2044 randerso Refactored to use IFPServer + * Oct 16, 2013 #2475 dgilling Better error handling for IRT activation. + * Mar 21, 2014 2726 rjpeter Updated wait for running loop. * * * @author njensen @@ -87,14 +88,8 @@ public class GFESiteActivation implements ISiteActivationListener { private static final String INIT_TASK_DETAILS = "Initialization:"; - private static final String SMART_INIT_TASK_DETAILS = "SmartInit:"; - private static final int LOCK_TASK_TIMEOUT = 180000; - // don't rerun the smart init fire if they have been run in the last 30 - // minutes - private static final int SMART_INIT_TIMEOUT = 1800000; - private static GFESiteActivation instance = new GFESiteActivation(); private boolean intialized = false; @@ -297,7 +292,7 @@ public class GFESiteActivation implements ISiteActivationListener { statusHandler.info("IFPServerConfigManager initializing..."); config = IFPServerConfigManager.initializeSite(siteID); statusHandler.info("Activating IFPServer..."); - IFPServer ifpServer = IFPServer.activateServer(siteID, config); + IFPServer.activateServer(siteID, config); } finally { statusHandler .handle(Priority.INFO, @@ -345,16 +340,7 @@ public class GFESiteActivation implements ISiteActivationListener { @Override public void run() { - long startTime = System.currentTimeMillis(); - // wait for system startup or at least 3 minutes - while (!EDEXUtil.isRunning() - || (System.currentTimeMillis() > (startTime + 180000))) { - try { - Thread.sleep(15000); - } catch (InterruptedException e) { - - } - } + EDEXUtil.waitForRunning(); Map fetchATConfig = new HashMap(); fetchATConfig.put("siteId", configRef.getSiteID().get(0)); diff --git a/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/isc/IscSendJob.java b/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/isc/IscSendJob.java deleted file mode 100644 index e96d5562ad..0000000000 --- a/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/isc/IscSendJob.java +++ /dev/null @@ -1,267 +0,0 @@ -/** - * This software was developed and / or modified by Raytheon Company, - * pursuant to Contract DG133W-05-CQ-1067 with the US Government. - * - * U.S. EXPORT CONTROLLED TECHNICAL DATA - * This software product contains export-restricted data whose - * export/transfer/disclosure is restricted by U.S. law. Dissemination - * to non-U.S. persons whether in the United States or abroad requires - * an export license or other authorization. - * - * Contractor Name: Raytheon Company - * Contractor Address: 6825 Pine Street, Suite 340 - * Mail Stop B8 - * Omaha, NE 68106 - * 402.291.0100 - * - * See the AWIPS II Master Rights File ("Master Rights File.pdf") for - * further licensing information. - **/ - -package com.raytheon.edex.plugin.gfe.isc; - -import java.net.InetAddress; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import jep.JepException; - -import com.raytheon.edex.plugin.gfe.config.GFESiteActivation; -import com.raytheon.edex.plugin.gfe.config.IFPServerConfig; -import com.raytheon.edex.plugin.gfe.config.IFPServerConfigManager; -import com.raytheon.edex.plugin.gfe.exception.GfeConfigurationException; -import com.raytheon.edex.plugin.gfe.server.IFPServer; -import com.raytheon.edex.plugin.gfe.server.database.GridDatabase; -import com.raytheon.edex.plugin.gfe.util.SendNotifications; -import com.raytheon.uf.common.dataplugin.gfe.GridDataHistory; -import com.raytheon.uf.common.dataplugin.gfe.db.objects.DatabaseID; -import com.raytheon.uf.common.dataplugin.gfe.db.objects.ParmID; -import com.raytheon.uf.common.dataplugin.gfe.server.message.ServerResponse; -import com.raytheon.uf.common.dataplugin.gfe.server.notify.GridHistoryUpdateNotification; -import com.raytheon.uf.common.message.WsId; -import com.raytheon.uf.common.status.IUFStatusHandler; -import com.raytheon.uf.common.status.UFStatus; -import com.raytheon.uf.common.time.TimeRange; -import com.raytheon.uf.edex.core.EDEXUtil; - -/** - * Class to for running the isc scripts - * - *

- * 
- * SOFTWARE HISTORY
- * 
- * Date         Ticket#     Engineer    Description
- * ------------ ----------  ----------- --------------------------
- * 07/06/09      1995       bphillip    Initial release
- * 04/06/12      #457       dgilling    Move call to delete records
- *                                      from queue into run().
- * 04/23/13      #1949      rjpeter     Move setting of lastSentTime to dao
- *                                      and removed initial delay.
- * 06/13/13      2044       randerso    Refactored to use IFPServer
- * 
- * - * @author bphillip - * @version 1 - */ -public class IscSendJob implements Runnable { - - private static final transient IUFStatusHandler statusHandler = UFStatus - .getHandler(IscSendJob.class); - - /** Date format for formatting dates for use with iscExtract script */ - private static final SimpleDateFormat ISC_EXTRACT_DATE = new SimpleDateFormat( - "yyyyMMdd_HHmm"); - - private final Map scripts; - - private int runningTimeOutMillis; - - private int threadSleepInterval; - - /** - * Constructs a new IscSendJob - * - * @param siteID - * the site ID - * - * @param cmdQueue - */ - public IscSendJob() { - scripts = new HashMap(); - runningTimeOutMillis = 300000; - threadSleepInterval = 30000; - } - - @Override - public void run() { - while (!EDEXUtil.isRunning()) { - try { - Thread.sleep(threadSleepInterval); - } catch (Throwable t) { - // ignore - } - } - - try { - // run forever - while (true) { - IscSendRecord record = SendIscTransactions - .getNextSendJob(runningTimeOutMillis); - if (record != null) { - runIscSend(record); - SendIscTransactions.removeSendJob(record); - } else { - try { - Thread.sleep(threadSleepInterval); - } catch (Exception e) { - // ignore - } - } - } - } finally { - // Make sure OS resources are released at thread death - for (IscSendScript script : scripts.values()) { - script.dispose(); - } - } - } - - private void runIscSend(IscSendRecord request) { - try { - ParmID id = request.getParmID(); - TimeRange tr = request.getTimeRange(); - String xmlDest = request.getXmlDest(); - String siteId = id.getDbId().getSiteId(); - - if (!GFESiteActivation.getInstance().getActiveSites() - .contains(siteId)) { - statusHandler.warn("Attempted to send " + id - + " for deactivated site " + siteId + "."); - return; - } - - statusHandler.info("Starting isc for " + id.toString() + " " - + tr.toString() + " " + xmlDest); - - Map cmd = new HashMap(); - cmd.put("parmNames", Arrays.asList(id.getParmName())); - cmd.put("databaseName", id.getDbId().getModelId()); - cmd.put("startTime", ISC_EXTRACT_DATE.format(tr.getStart())); - cmd.put("endTime", ISC_EXTRACT_DATE.format(tr.getEnd())); - - // destination server XML, might be empty - // the -D switch is a file location containing the xml - // information - if (!xmlDest.isEmpty()) { - cmd.put("destinations", xmlDest); - } - - try { - IFPServerConfig config = IFPServerConfigManager - .getServerConfig(siteId); - // IRT table address - cmd.put("irtTableAddressA", config.iscRoutingTableAddress() - .get("ANCF")); - cmd.put("irtTableAddressB", config.iscRoutingTableAddress() - .get("BNCF")); - // xmt script - cmd.put("transmitScript", config.transmitScript()); - // our server host, port, protocol, our mhs id, and our site id - cmd.put("ourServerHost", config.getServerHost()); - cmd.put("ourServerPort", String.valueOf(config.getRpcPort())); - cmd.put("ourServerProtocol", - String.valueOf(config.getProtocolVersion())); - cmd.put("ourMHSid", config.getMhsid()); - cmd.put("ourSiteID", config.getSiteID().get(0)); - } catch (GfeConfigurationException e) { - statusHandler.error( - "Unable to retrieve site configuration for site " - + siteId, e); - return; - } - - try { - IscSendScript script = scripts.get(siteId); - if (script == null) { - script = IscSendScriptFactory - .constructIscSendScript(siteId); - scripts.put(siteId, script); - } - script.execute(cmd); - } catch (JepException e) { - statusHandler.error("Error executing iscExtract.", e); - return; - } - - try { - DatabaseID dbId = id.getDbId(); - IFPServer ifpServer = IFPServer.getActiveServer(dbId - .getSiteId()); - if (ifpServer != null) { - GridDatabase gridDb = ifpServer.getGridParmMgr() - .getDatabase(dbId); - if (gridDb != null) { - ServerResponse>> sr = gridDb - .updateSentTime(id, tr, new Date()); - if (sr.isOkay()) { - WsId wsId = new WsId(InetAddress.getLocalHost(), - "ISC", "ISC"); - List notifications = new ArrayList( - 1); - Map> histories = sr - .getPayload(); - notifications - .add(new GridHistoryUpdateNotification(id, - histories, wsId, siteId)); - SendNotifications.send(notifications); - - } else { - statusHandler - .error("Error updating last sent times in GFERecords: " - + sr.getMessages()); - } - } else { - // no such database exists - statusHandler - .error("Error processing ISC send request for :" - + dbId - + ", the database does not exist."); - } - } else { - // no active server for request - statusHandler - .error("Error processing ISC send request for :" - + dbId + ", no active IFPServer for site."); - } - } catch (Exception e) { - statusHandler.error( - "Error updating last sent times in GFERecords.", e); - } - - } catch (Throwable t) { - statusHandler.error("Exception in ISCSendJob: ", t); - } - } - - public int getRunningTimeOutMillis() { - return runningTimeOutMillis; - } - - public void setRunningTimeOutMillis(int runningTimeOutMillis) { - this.runningTimeOutMillis = runningTimeOutMillis; - } - - public int getThreadSleepInterval() { - return threadSleepInterval; - } - - public void setThreadSleepInterval(int threadSleepInterval) { - this.threadSleepInterval = threadSleepInterval; - } -} \ No newline at end of file diff --git a/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/isc/SendIscSrv.java b/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/isc/SendIscSrv.java index 5e703ab8c9..a5368f1ebd 100644 --- a/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/isc/SendIscSrv.java +++ b/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/isc/SendIscSrv.java @@ -19,7 +19,33 @@ **/ package com.raytheon.edex.plugin.gfe.isc; -import java.util.concurrent.Executor; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import jep.JepException; + +import com.raytheon.edex.plugin.gfe.config.GFESiteActivation; +import com.raytheon.edex.plugin.gfe.config.IFPServerConfig; +import com.raytheon.edex.plugin.gfe.config.IFPServerConfigManager; +import com.raytheon.edex.plugin.gfe.exception.GfeConfigurationException; +import com.raytheon.edex.plugin.gfe.server.IFPServer; +import com.raytheon.edex.plugin.gfe.server.database.GridDatabase; +import com.raytheon.edex.plugin.gfe.util.SendNotifications; +import com.raytheon.uf.common.dataplugin.gfe.GridDataHistory; +import com.raytheon.uf.common.dataplugin.gfe.db.objects.DatabaseID; +import com.raytheon.uf.common.dataplugin.gfe.db.objects.ParmID; +import com.raytheon.uf.common.dataplugin.gfe.server.message.ServerResponse; +import com.raytheon.uf.common.dataplugin.gfe.server.notify.GridHistoryUpdateNotification; +import com.raytheon.uf.common.message.WsId; +import com.raytheon.uf.common.status.IUFStatusHandler; +import com.raytheon.uf.common.status.UFStatus; +import com.raytheon.uf.common.time.TimeRange; +import com.raytheon.uf.edex.core.EdexTimerBasedThread; /** * Service that runs ISC send jobs. Along with IscSendQueue, this class roughly @@ -31,28 +57,183 @@ import java.util.concurrent.Executor; * * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- - * Oct 20, 2011 dgilling Initial creation - * + * Oct 20, 2011 dgilling Initial creation + * May 19, 2014 2726 rjpeter Integrate IscSendJob for graceful shutdown. * * * @author dgilling * @version 1.0 */ -public class SendIscSrv { +public class SendIscSrv extends EdexTimerBasedThread { + private final transient IUFStatusHandler statusHandler = UFStatus + .getHandler(SendIscSrv.class); - private final SendIscSrvConfig cfg; + protected int runningTimeOutMillis; - private final Executor executor; + /** Date format for formatting dates for use with iscExtract script */ + protected static final SimpleDateFormat ISC_EXTRACT_DATE = new SimpleDateFormat( + "yyyyMMdd_HHmm"); - public SendIscSrv(SendIscSrvConfig config) { - this.cfg = config; - this.executor = config.getExecutor(); - for (int i = 0; i < cfg.getThreads(); i++) { - IscSendJob thread = new IscSendJob(); - thread.setRunningTimeOutMillis(cfg.getRunningTimeOutMillis()); - thread.setThreadSleepInterval(cfg.getThreadSleepInterval()); - executor.execute(thread); + protected final ThreadLocal> scripts = new ThreadLocal>() { + + @Override + protected Map initialValue() { + return new HashMap(); + } + + }; + + public SendIscSrv() { + } + + public int getRunningTimeOutMillis() { + return runningTimeOutMillis; + } + + public void setRunningTimeOutMillis(int runningTimeOutMillis) { + this.runningTimeOutMillis = runningTimeOutMillis; + } + + @Override + public String getThreadGroupName() { + return "iscSendThreadPool"; + } + + @Override + public void process() throws Exception { + IscSendRecord record = null; + do { + record = SendIscTransactions.getNextSendJob(runningTimeOutMillis); + if (record != null) { + runIscSend(record); + SendIscTransactions.removeSendJob(record); + } + } while (record != null); + } + + @Override + public void dispose() { + super.dispose(); + // Make sure OS resources are released at thread death + for (IscSendScript script : scripts.get().values()) { + script.dispose(); + } + } + + private void runIscSend(IscSendRecord request) { + try { + ParmID id = request.getParmID(); + TimeRange tr = request.getTimeRange(); + String xmlDest = request.getXmlDest(); + String siteId = id.getDbId().getSiteId(); + + if (!GFESiteActivation.getInstance().getActiveSites() + .contains(siteId)) { + statusHandler.warn("Attempted to send " + id + + " for deactivated site " + siteId + "."); + return; + } + + statusHandler.info("Starting isc for " + id.toString() + " " + + tr.toString() + " " + xmlDest); + + Map cmd = new HashMap(); + cmd.put("parmNames", Arrays.asList(id.getParmName())); + cmd.put("databaseName", id.getDbId().getModelId()); + cmd.put("startTime", ISC_EXTRACT_DATE.format(tr.getStart())); + cmd.put("endTime", ISC_EXTRACT_DATE.format(tr.getEnd())); + + // destination server XML, might be empty + // the -D switch is a file location containing the xml + // information + if (!xmlDest.isEmpty()) { + cmd.put("destinations", xmlDest); + } + + try { + IFPServerConfig config = IFPServerConfigManager + .getServerConfig(siteId); + // IRT table address + cmd.put("irtTableAddressA", config.iscRoutingTableAddress() + .get("ANCF")); + cmd.put("irtTableAddressB", config.iscRoutingTableAddress() + .get("BNCF")); + // xmt script + cmd.put("transmitScript", config.transmitScript()); + // our server host, port, protocol, our mhs id, and our site id + cmd.put("ourServerHost", config.getServerHost()); + cmd.put("ourServerPort", String.valueOf(config.getRpcPort())); + cmd.put("ourServerProtocol", + String.valueOf(config.getProtocolVersion())); + cmd.put("ourMHSid", config.getMhsid()); + cmd.put("ourSiteID", config.getSiteID().get(0)); + } catch (GfeConfigurationException e) { + statusHandler.error( + "Unable to retrieve site configuration for site " + + siteId, e); + return; + } + + try { + IscSendScript script = scripts.get().get(siteId); + if (script == null) { + script = IscSendScriptFactory + .constructIscSendScript(siteId); + scripts.get().put(siteId, script); + } + script.execute(cmd); + } catch (JepException e) { + statusHandler.error("Error executing iscExtract.", e); + return; + } + + try { + DatabaseID dbId = id.getDbId(); + IFPServer ifpServer = IFPServer.getActiveServer(dbId + .getSiteId()); + if (ifpServer != null) { + GridDatabase gridDb = ifpServer.getGridParmMgr() + .getDatabase(dbId); + if (gridDb != null) { + ServerResponse>> sr = gridDb + .updateSentTime(id, tr, new Date()); + if (sr.isOkay()) { + WsId wsId = new WsId(null, "ISC", "ISC"); + List notifications = new ArrayList( + 1); + Map> histories = sr + .getPayload(); + notifications + .add(new GridHistoryUpdateNotification(id, + histories, wsId, siteId)); + SendNotifications.send(notifications); + + } else { + statusHandler + .error("Error updating last sent times in GFERecords: " + + sr.getMessages()); + } + } else { + // no such database exists + statusHandler + .error("Error processing ISC send request for :" + + dbId + + ", the database does not exist."); + } + } else { + // no active server for request + statusHandler + .error("Error processing ISC send request for :" + + dbId + ", no active IFPServer for site."); + } + } catch (Exception e) { + statusHandler.error( + "Error updating last sent times in GFERecords.", e); + } + + } catch (Throwable t) { + statusHandler.error("Exception in SendIscSrv: ", t); } } } diff --git a/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/isc/SendIscSrvConfig.java b/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/isc/SendIscSrvConfig.java deleted file mode 100644 index 92e62c3ef9..0000000000 --- a/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/isc/SendIscSrvConfig.java +++ /dev/null @@ -1,82 +0,0 @@ -/** - * This software was developed and / or modified by Raytheon Company, - * pursuant to Contract DG133W-05-CQ-1067 with the US Government. - * - * U.S. EXPORT CONTROLLED TECHNICAL DATA - * This software product contains export-restricted data whose - * export/transfer/disclosure is restricted by U.S. law. Dissemination - * to non-U.S. persons whether in the United States or abroad requires - * an export license or other authorization. - * - * Contractor Name: Raytheon Company - * Contractor Address: 6825 Pine Street, Suite 340 - * Mail Stop B8 - * Omaha, NE 68106 - * 402.291.0100 - * - * See the AWIPS II Master Rights File ("Master Rights File.pdf") for - * further licensing information. - **/ -package com.raytheon.edex.plugin.gfe.isc; - -import java.util.concurrent.Executor; - -/** - * Send ISC service configuration. - * - *
- * 
- * SOFTWARE HISTORY
- * 
- * Date         Ticket#    Engineer    Description
- * ------------ ---------- ----------- --------------------------
- * Oct 20, 2011            dgilling    Initial creation
- * Apr 30, 2013 1949       rjpeter     Removed initial delay.
- * 
- * - * @author dgilling - * @version 1.0 - */ - -public class SendIscSrvConfig { - - protected int threads; - - protected Executor executor; - - protected int runningTimeOutMillis; - - protected int threadSleepInterval; - - public int getThreads() { - return threads; - } - - public void setThreads(int threads) { - this.threads = threads; - } - - public Executor getExecutor() { - return executor; - } - - public void setExecutor(Executor executor) { - this.executor = executor; - } - - public int getRunningTimeOutMillis() { - return runningTimeOutMillis; - } - - public void setRunningTimeOutMillis(int runningTimeOutMillis) { - this.runningTimeOutMillis = runningTimeOutMillis; - } - - public int getThreadSleepInterval() { - return threadSleepInterval; - } - - public void setThreadSleepInterval(int threadSleepInterval) { - this.threadSleepInterval = threadSleepInterval; - } -} diff --git a/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/smartinit/SmartInitSrv.java b/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/smartinit/SmartInitSrv.java index 2b68e40722..6e8f75ddfb 100644 --- a/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/smartinit/SmartInitSrv.java +++ b/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/smartinit/SmartInitSrv.java @@ -25,13 +25,9 @@ import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.concurrent.Executor; import jep.JepException; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - import com.raytheon.edex.plugin.gfe.server.IFPServer; import com.raytheon.uf.common.dataplugin.gfe.db.objects.DatabaseID; import com.raytheon.uf.common.localization.IPathManager; @@ -39,10 +35,10 @@ import com.raytheon.uf.common.localization.LocalizationContext; import com.raytheon.uf.common.localization.LocalizationContext.LocalizationLevel; import com.raytheon.uf.common.localization.LocalizationContext.LocalizationType; import com.raytheon.uf.common.localization.PathManagerFactory; +import com.raytheon.uf.common.status.IUFStatusHandler; +import com.raytheon.uf.common.status.UFStatus; import com.raytheon.uf.common.util.FileUtil; -import com.raytheon.uf.edex.core.EDEXUtil; -import com.raytheon.uf.edex.core.props.EnvProperties; -import com.raytheon.uf.edex.core.props.PropertiesFactory; +import com.raytheon.uf.edex.core.EdexTimerBasedThread; /** * Service that runs smart inits @@ -58,168 +54,154 @@ import com.raytheon.uf.edex.core.props.PropertiesFactory; * Aug 24, 2013 #1949 rjpeter Updated start up logic * Jun 13, 2013 #2044 randerso Refactored to use IFPServer, * added support to run init for all valid times + * Mar 14, 2014 2726 rjpeter Implement graceful shutdown. * * * @author njensen * @version 1.0 */ -public class SmartInitSrv { +public class SmartInitSrv extends EdexTimerBasedThread { + protected static final transient IUFStatusHandler statusHandler = UFStatus + .getHandler(SmartInitSrv.class); private final Map cachedInterpreters = new HashMap(); - private static boolean enabled = true; + protected int pendingInitMinTimeMillis = 120000; - protected final SmartInitSrvConfig cfg; + protected int runningInitTimeOutMillis = 600000; - protected final Executor executor; - - static { - EnvProperties env = PropertiesFactory.getInstance().getEnvProperties(); - enabled = Boolean.parseBoolean(env.getEnvValue("GFESMARTINIT")); + public SmartInitSrv() { } - public SmartInitSrv(SmartInitSrvConfig config) { - cfg = config; - this.executor = config.getExecutor(); - for (int i = 0; i < cfg.getThreads(); i++) { - SmartInitThread thread = new SmartInitThread(); - thread.pendingInitMinTimeMillis = cfg.getPendingInitMinTimeMillis(); - thread.runningInitTimeOutMillis = cfg.getRunningInitTimeOutMillis(); - thread.threadSleepInterval = cfg.getThreadSleepInterval(); - executor.execute(thread); - } + @Override + public String getThreadGroupName() { + return "smartInitThreadPool"; } - protected class SmartInitThread implements Runnable { - // default of 2 minutes - private int pendingInitMinTimeMillis = 120000; - - private int runningInitTimeOutMillis = 600000; - - private int threadSleepInterval = 30000; - - private final transient Log logger = LogFactory.getLog(getClass()); - - @Override - public void run() { - try { - // Wait for server to come fully up due to route dependencies - while (!EDEXUtil.isRunning()) { - try { - Thread.sleep(threadSleepInterval); - } catch (InterruptedException e) { - // ignore - } - } - - // run forever - while (true) { - SmartInitRecord record = SmartInitTransactions - .getSmartInitToRun(pendingInitMinTimeMillis, - runningInitTimeOutMillis); - if (record != null) { - runSmartInit(record); - } else { - try { - Thread.sleep(threadSleepInterval); - } catch (Exception e) { - // ignore - } - } - } - } finally { - // Make sure OS resources are released at thread death - SmartInitScript script = cachedInterpreters.remove(Thread - .currentThread().getId()); - script.dispose(); + @Override + public void process() throws Exception { + SmartInitRecord record = null; + do { + record = SmartInitTransactions.getSmartInitToRun( + pendingInitMinTimeMillis, runningInitTimeOutMillis); + if (record != null) { + runSmartInit(record); } - } + } while (record != null); + } - public void runSmartInit(SmartInitRecord record) { - if (enabled) { + @Override + public void dispose() { + super.dispose(); + + // Make sure OS resources are released at thread death + SmartInitScript script = cachedInterpreters.remove(Thread + .currentThread().getId()); + if (script != null) { + script.dispose(); + } + } + + public void runSmartInit(SmartInitRecord record) { + try { + SmartInitScript initScript = null; + List sitePathsAdded = new ArrayList(2); + + String init = record.getSmartInit(); + String dbName = record.getDbName() + + (record.isManual() ? ":1" : ":0"); + Date validTime = record.getId().getValidTime(); + if (SmartInitRecord.ALL_TIMES.equals(validTime)) { + validTime = null; + } + + DatabaseID db = new DatabaseID(record.getDbName()); + if (IFPServer.getActiveSites().contains(db.getSiteId())) { try { - SmartInitScript initScript = null; - List sitePathsAdded = new ArrayList(2); + long id = Thread.currentThread().getId(); + initScript = cachedInterpreters.get(id); - String init = record.getSmartInit(); - String dbName = record.getDbName() - + (record.isManual() ? ":1" : ":0"); - Date validTime = record.getId().getValidTime(); - if (SmartInitRecord.ALL_TIMES.equals(validTime)) { - validTime = null; + if (initScript == null) { + initScript = SmartInitFactory.constructInit(); + cachedInterpreters.put(id, initScript); } - DatabaseID db = new DatabaseID(record.getDbName()); - if (IFPServer.getActiveSites().contains(db.getSiteId())) { - try { - long id = Thread.currentThread().getId(); - initScript = cachedInterpreters.get(id); + IPathManager pathMgr = PathManagerFactory.getPathManager(); + LocalizationContext ctx = pathMgr.getContextForSite( + LocalizationType.EDEX_STATIC, db.getSiteId()); + LocalizationContext baseCtx = pathMgr.getContext( + LocalizationType.EDEX_STATIC, + LocalizationLevel.BASE); - if (initScript == null) { - initScript = SmartInitFactory.constructInit(); - cachedInterpreters.put(id, initScript); - } - - IPathManager pathMgr = PathManagerFactory - .getPathManager(); - LocalizationContext ctx = pathMgr - .getContextForSite( - LocalizationType.EDEX_STATIC, - db.getSiteId()); - LocalizationContext baseCtx = pathMgr.getContext( - LocalizationType.EDEX_STATIC, - LocalizationLevel.BASE); - - File file = pathMgr.getFile(ctx, "smartinit"); - if ((file != null) && file.exists()) { - initScript.addSitePath(file.getPath(), pathMgr - .getFile(baseCtx, "smartinit") - .getPath()); - sitePathsAdded.add(file.getPath()); - } - file = pathMgr.getFile(ctx, - FileUtil.join("config", "gfe")); - if ((file != null) && file.exists()) { - initScript.addSitePath( - file.getPath(), - pathMgr.getFile(baseCtx, - FileUtil.join("config", "gfe")) + File file = pathMgr.getFile(ctx, "smartinit"); + if ((file != null) && file.exists()) { + initScript + .addSitePath(file.getPath(), + pathMgr.getFile(baseCtx, "smartinit") .getPath()); - sitePathsAdded.add(file.getPath()); - } - - HashMap argMap = new HashMap(); - argMap.put("dbName", dbName); - argMap.put("model", init); - argMap.put("validTime", validTime); - - initScript.execute(argMap); - } catch (Throwable e) { - logger.error("Error running smart init for " - + record.getId(), e); - } finally { - try { - for (String path : sitePathsAdded) { - initScript.removeSitePath(path); - } - } catch (JepException e) { - this.logger - .error("Error cleaning up smart init interpreter's sys.path", - e); - } - } - } else { - this.logger.warn("Site " + db.getSiteId() - + " has been disabled. Smart init for " - + record.getDbName() - + " will not be processed."); + sitePathsAdded.add(file.getPath()); + } + file = pathMgr.getFile(ctx, FileUtil.join("config", "gfe")); + if ((file != null) && file.exists()) { + initScript.addSitePath( + file.getPath(), + pathMgr.getFile(baseCtx, + FileUtil.join("config", "gfe")) + .getPath()); + sitePathsAdded.add(file.getPath()); + } + + HashMap argMap = new HashMap(); + argMap.put("dbName", dbName); + argMap.put("model", init); + argMap.put("validTime", validTime); + + initScript.execute(argMap); + } catch (Throwable e) { + statusHandler.error("Error running smart init for " + + record.getId(), e); + } finally { + try { + for (String path : sitePathsAdded) { + initScript.removeSitePath(path); + } + } catch (JepException e) { + statusHandler + .error("Error cleaning up smart init interpreter's sys.path", + e); } - } catch (Throwable t) { - this.logger.error("Error in SmartInitSrv", t); } - SmartInitTransactions.removeSmartInit(record); + } else { + statusHandler.warn("Site " + db.getSiteId() + + " has been disabled. Smart init for " + + record.getDbName() + " will not be processed."); } + } catch (Throwable t) { + statusHandler.error("Error in SmartInitSrv", t); } + SmartInitTransactions.removeSmartInit(record); + } + + @Override + public void postStop() { + SmartInitQueue.getQueue().fireSmartInit(); + super.postStop(); + } + + public int getPendingInitMinTimeMillis() { + return pendingInitMinTimeMillis; + } + + public void setPendingInitMinTimeMillis(int pendingInitMinTimeMillis) { + this.pendingInitMinTimeMillis = pendingInitMinTimeMillis; + } + + public int getRunningInitTimeOutMillis() { + return runningInitTimeOutMillis; + } + + public void setRunningInitTimeOutMillis(int runningInitTimeOutMillis) { + this.runningInitTimeOutMillis = runningInitTimeOutMillis; } } diff --git a/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/smartinit/SmartInitSrvConfig.java b/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/smartinit/SmartInitSrvConfig.java deleted file mode 100644 index cf463847b5..0000000000 --- a/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/smartinit/SmartInitSrvConfig.java +++ /dev/null @@ -1,91 +0,0 @@ -/** - * This software was developed and / or modified by Raytheon Company, - * pursuant to Contract DG133W-05-CQ-1067 with the US Government. - * - * U.S. EXPORT CONTROLLED TECHNICAL DATA - * This software product contains export-restricted data whose - * export/transfer/disclosure is restricted by U.S. law. Dissemination - * to non-U.S. persons whether in the United States or abroad requires - * an export license or other authorization. - * - * Contractor Name: Raytheon Company - * Contractor Address: 6825 Pine Street, Suite 340 - * Mail Stop B8 - * Omaha, NE 68106 - * 402.291.0100 - * - * See the AWIPS II Master Rights File ("Master Rights File.pdf") for - * further licensing information. - **/ -package com.raytheon.edex.plugin.gfe.smartinit; - -import java.util.concurrent.Executor; - -/** - * Smart Init Server config. - * - *
- * 
- * SOFTWARE HISTORY
- * Date         Ticket#    Engineer    Description
- * ------------ ---------- ----------- --------------------------
- * Sep 24, 2010 #7277      rjpeter     Initial creation
- * Apr 23, 2013 #1949      rjpeter     Removed initial delay
- * 
- * - * @author rjpeter - * @version 1.0 - */ - -public class SmartInitSrvConfig { - protected int threads; - - protected Executor executor; - - protected int pendingInitMinTimeMillis; - - protected int runningInitTimeOutMillis; - - protected int threadSleepInterval; - - public int getThreads() { - return threads; - } - - public void setThreads(int threads) { - this.threads = threads; - } - - public Executor getExecutor() { - return executor; - } - - public void setExecutor(Executor executor) { - this.executor = executor; - } - - public int getPendingInitMinTimeMillis() { - return pendingInitMinTimeMillis; - } - - public void setPendingInitMinTimeMillis(int pendingInitMinTimeMillis) { - this.pendingInitMinTimeMillis = pendingInitMinTimeMillis; - } - - public int getRunningInitTimeOutMillis() { - return runningInitTimeOutMillis; - } - - public void setRunningInitTimeOutMillis(int runningInitTimeOutMillis) { - this.runningInitTimeOutMillis = runningInitTimeOutMillis; - } - - public int getThreadSleepInterval() { - return threadSleepInterval; - } - - public void setThreadSleepInterval(int threadSleepInterval) { - this.threadSleepInterval = threadSleepInterval; - } - -} diff --git a/edexOsgi/com.raytheon.edex.plugin.goessounding/res/spring/goessounding-ingest.xml b/edexOsgi/com.raytheon.edex.plugin.goessounding/res/spring/goessounding-ingest.xml index 5f7aa56c3c..7ff0af9962 100644 --- a/edexOsgi/com.raytheon.edex.plugin.goessounding/res/spring/goessounding-ingest.xml +++ b/edexOsgi/com.raytheon.edex.plugin.goessounding/res/spring/goessounding-ingest.xml @@ -15,16 +15,9 @@
- - - - + errorHandlerRef="errorHandler"> - + @@ -63,14 +55,15 @@
- + - + + diff --git a/edexOsgi/com.raytheon.edex.plugin.grib/utility/edex_static/base/grib/thinnedModels/UkmetHR-NH.xml b/edexOsgi/com.raytheon.edex.plugin.grib/utility/edex_static/base/grib/thinnedModels/UkmetHR-NH.xml index 5325335d6b..964db69089 100644 --- a/edexOsgi/com.raytheon.edex.plugin.grib/utility/edex_static/base/grib/thinnedModels/UkmetHR-NH.xml +++ b/edexOsgi/com.raytheon.edex.plugin.grib/utility/edex_static/base/grib/thinnedModels/UkmetHR-NH.xml @@ -1,4 +1,4 @@ - + diff --git a/edexOsgi/com.raytheon.edex.plugin.obs/res/spring/obs-ingest-metarshef.xml b/edexOsgi/com.raytheon.edex.plugin.obs/res/spring/obs-ingest-metarshef.xml index 3fa8f85c54..d8aae45577 100644 --- a/edexOsgi/com.raytheon.edex.plugin.obs/res/spring/obs-ingest-metarshef.xml +++ b/edexOsgi/com.raytheon.edex.plugin.obs/res/spring/obs-ingest-metarshef.xml @@ -5,15 +5,8 @@ http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd"> - - - - - + errorHandlerRef="errorHandler"> diff --git a/edexOsgi/com.raytheon.edex.plugin.obs/res/spring/obs-ingest.xml b/edexOsgi/com.raytheon.edex.plugin.obs/res/spring/obs-ingest.xml index ed112a4f3f..ef1a7969e7 100644 --- a/edexOsgi/com.raytheon.edex.plugin.obs/res/spring/obs-ingest.xml +++ b/edexOsgi/com.raytheon.edex.plugin.obs/res/spring/obs-ingest.xml @@ -1,8 +1,7 @@ + xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd"> diff --git a/edexOsgi/com.raytheon.edex.plugin.poessounding/res/spring/poessounding-ingest.xml b/edexOsgi/com.raytheon.edex.plugin.poessounding/res/spring/poessounding-ingest.xml index a5acee9edc..70b7d67a9b 100644 --- a/edexOsgi/com.raytheon.edex.plugin.poessounding/res/spring/poessounding-ingest.xml +++ b/edexOsgi/com.raytheon.edex.plugin.poessounding/res/spring/poessounding-ingest.xml @@ -12,15 +12,9 @@ - - - - + errorHandlerRef="errorHandler"> - - - - + + + + errorHandlerRef="errorHandler"> diff --git a/edexOsgi/com.raytheon.edex.plugin.shef/res/spring/shef-ingest.xml b/edexOsgi/com.raytheon.edex.plugin.shef/res/spring/shef-ingest.xml index cbeb83d0e8..e63a4bf572 100644 --- a/edexOsgi/com.raytheon.edex.plugin.shef/res/spring/shef-ingest.xml +++ b/edexOsgi/com.raytheon.edex.plugin.shef/res/spring/shef-ingest.xml @@ -44,22 +44,17 @@
- - - - - + + errorHandlerRef="errorHandler"> @@ -75,7 +70,7 @@ + errorHandlerRef="errorHandler"> diff --git a/edexOsgi/com.raytheon.edex.plugin.taf/res/spring/taf-ingest.xml b/edexOsgi/com.raytheon.edex.plugin.taf/res/spring/taf-ingest.xml index 651083abdb..63a6bb5378 100644 --- a/edexOsgi/com.raytheon.edex.plugin.taf/res/spring/taf-ingest.xml +++ b/edexOsgi/com.raytheon.edex.plugin.taf/res/spring/taf-ingest.xml @@ -18,15 +18,9 @@ - - - - + errorHandlerRef="errorHandler"> @@ -232,8 +231,7 @@ - + \ No newline at end of file diff --git a/edexOsgi/com.raytheon.edex.plugin.textlightning/res/spring/textlightning_ep-ingest.xml b/edexOsgi/com.raytheon.edex.plugin.textlightning/res/spring/textlightning_ep-ingest.xml index 5f5ada5907..8808d585c8 100644 --- a/edexOsgi/com.raytheon.edex.plugin.textlightning/res/spring/textlightning_ep-ingest.xml +++ b/edexOsgi/com.raytheon.edex.plugin.textlightning/res/spring/textlightning_ep-ingest.xml @@ -12,15 +12,9 @@ - - - - + errorHandlerRef="errorHandler"> - - - - - - - + + uri="clusteredquartz://warning/checkGeospatialData/?cron=${geospatial.updater.cron}" /> - - - + + + + - - + + + - + java.lang.Throwable - - \ No newline at end of file + + + + + + + + diff --git a/edexOsgi/com.raytheon.edex.plugin.warning/src/com/raytheon/edex/plugin/warning/gis/GenerateGeospatialDataRequestHandler.java b/edexOsgi/com.raytheon.edex.plugin.warning/src/com/raytheon/edex/plugin/warning/gis/GenerateGeospatialDataRequestHandler.java index 0fb5496a5f..8dc921c1c9 100644 --- a/edexOsgi/com.raytheon.edex.plugin.warning/src/com/raytheon/edex/plugin/warning/gis/GenerateGeospatialDataRequestHandler.java +++ b/edexOsgi/com.raytheon.edex.plugin.warning/src/com/raytheon/edex/plugin/warning/gis/GenerateGeospatialDataRequestHandler.java @@ -23,7 +23,7 @@ import com.raytheon.uf.common.dataplugin.warning.gis.GenerateGeospatialDataReque import com.raytheon.uf.common.serialization.comm.IRequestHandler; /** - * TODO Add Description + * Generates geospatial data on demand. * *
  * 
@@ -31,8 +31,8 @@ import com.raytheon.uf.common.serialization.comm.IRequestHandler;
  * 
  * Date         Ticket#    Engineer    Description
  * ------------ ---------- ----------- --------------------------
- * Jul 22, 2011            rjpeter     Initial creation
- * 
+ * Jul 22, 2011            rjpeter     Initial creation.
+ * May 19, 2014 2726       rjpeter     Updated call to GeospatialDataGenerator.
  * 
* * @author rjpeter @@ -41,6 +41,13 @@ import com.raytheon.uf.common.serialization.comm.IRequestHandler; public class GenerateGeospatialDataRequestHandler implements IRequestHandler { + final GeospatialDataGenerator dataGenerator; + + public GenerateGeospatialDataRequestHandler( + GeospatialDataGenerator dataGenerator) { + this.dataGenerator = dataGenerator; + } + /* * (non-Javadoc) * @@ -51,8 +58,8 @@ public class GenerateGeospatialDataRequestHandler implements @Override public Object handleRequest(GenerateGeospatialDataRequest request) throws Exception { - return GeospatialDataGenerator.generateGeoSpatialList( - request.getSite(), request.getMetaData()); + return dataGenerator.generateGeoSpatialList(request.getSite(), + request.getMetaData()); } } diff --git a/edexOsgi/com.raytheon.edex.plugin.warning/src/com/raytheon/edex/plugin/warning/gis/GeospatialDataGenerator.java b/edexOsgi/com.raytheon.edex.plugin.warning/src/com/raytheon/edex/plugin/warning/gis/GeospatialDataGenerator.java index 2ac8e2ef02..4af2dce791 100644 --- a/edexOsgi/com.raytheon.edex.plugin.warning/src/com/raytheon/edex/plugin/warning/gis/GeospatialDataGenerator.java +++ b/edexOsgi/com.raytheon.edex.plugin.warning/src/com/raytheon/edex/plugin/warning/gis/GeospatialDataGenerator.java @@ -20,13 +20,16 @@ package com.raytheon.edex.plugin.warning.gis; import java.sql.Timestamp; +import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Arrays; +import java.util.Calendar; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.TimeZone; import javax.xml.bind.JAXBException; @@ -62,6 +65,8 @@ import com.raytheon.uf.common.serialization.SingleTypeJAXBManager; import com.raytheon.uf.common.status.IUFStatusHandler; import com.raytheon.uf.common.status.UFStatus; import com.raytheon.uf.common.status.UFStatus.Priority; +import com.raytheon.uf.edex.core.EDEXUtil; +import com.raytheon.uf.edex.core.EdexException; 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; @@ -97,6 +102,7 @@ import com.vividsolutions.jts.simplify.TopologyPreservingSimplifier; * May 7, 2013 15690 Qinglu Lin Added convertToMultiPolygon() and updated queryGeospatialData(). * Oct 22, 2013 2361 njensen Use JAXBManager for XML * Feb 07, 2014 16090 mgamazaychikov Changed visibility of some methods + * Mar 19, 2014 2726 rjpeter Made singleton instance. * * * @author rjpeter @@ -104,14 +110,19 @@ import com.vividsolutions.jts.simplify.TopologyPreservingSimplifier; */ public class GeospatialDataGenerator { - - private static final transient IUFStatusHandler statusHandler = UFStatus + private final IUFStatusHandler statusHandler = UFStatus .getHandler(GeospatialDataGenerator.class); - private static final SingleTypeJAXBManager jaxb = SingleTypeJAXBManager + private final SingleTypeJAXBManager jaxb = SingleTypeJAXBManager .createWithoutException(GeospatialTimeSet.class); - public static void generateUniqueGeospatialMetadataGeometries() { + private final String updaterEndpoint; + + public GeospatialDataGenerator(String updaterEndpoint) { + this.updaterEndpoint = updaterEndpoint; + } + + public void generateUniqueGeospatialMetadataGeometries() { String mySite = SiteUtil.getSite(); DialogConfiguration dialogConfig = null; @@ -129,7 +140,7 @@ public class GeospatialDataGenerator { for (String site : sites) { statusHandler.handle(Priority.INFO, - "Generating warngen geometries for site: " + site); + "Checking warngen geometries for site: " + site); for (GeospatialMetadata md : metaDataSet) { try { generateGeoSpatialList(site, md); @@ -143,7 +154,7 @@ public class GeospatialDataGenerator { } } - public static Set getMetaDataSet(List sites, + public Set getMetaDataSet(List sites, List templates) { Set metaDataSet = new HashSet(); @@ -178,7 +189,8 @@ public class GeospatialDataGenerator { } return metaDataSet; } - static List getBackupSites(DialogConfiguration dialogConfig) { + + public static List getBackupSites(DialogConfiguration dialogConfig) { String[] CWAs = dialogConfig.getBackupCWAs().split(","); List rval = new ArrayList(CWAs.length + 1); for (String s : CWAs) { @@ -189,7 +201,7 @@ public class GeospatialDataGenerator { return rval; } - static List getTemplates(DialogConfiguration dialogConfig) { + public static List getTemplates(DialogConfiguration dialogConfig) { String[] mainProducts = dialogConfig.getMainWarngenProducts() .split(","); String[] otherProducts = dialogConfig.getOtherWarngenProducts().split( @@ -209,7 +221,7 @@ public class GeospatialDataGenerator { return rval; } - public static GeospatialDataSet generateGeoSpatialList(String site, + public GeospatialDataSet generateGeoSpatialList(String site, GeospatialMetadata metaData) throws SpatialException { GeospatialDataSet dataSet = null; String file = generateGeoDataFilename(metaData); @@ -307,6 +319,19 @@ public class GeospatialDataGenerator { // save to disk try { persistGeoData(site, lastRunTimeMap, curTime, dataSet); + + if (updaterEndpoint != null) { + String updatedTimeStamp = getTimeStamp(curTime, + lastRunTime); + + try { + EDEXUtil.getMessageProducer().sendAsync( + updaterEndpoint, updatedTimeStamp); + } catch (EdexException e) { + statusHandler.error("Could not send message to " + + updaterEndpoint, e); + } + } } catch (Exception e) { statusHandler.handle(Priority.WARN, "Error occurred persisting area geometry data", e); @@ -320,7 +345,7 @@ public class GeospatialDataGenerator { return dataSet; } - public static GeospatialMetadata getMetaData(WarngenConfiguration template) { + public GeospatialMetadata getMetaData(WarngenConfiguration template) { GeospatialMetadata rval = new GeospatialMetadata(); GeospatialConfiguration geoConfig = template.getGeospatialConfig(); AreaSourceConfiguration areaConfig = template.getHatchedAreaSource(); @@ -346,7 +371,7 @@ public class GeospatialDataGenerator { return rval; } - static GeospatialTime queryForCurrentTimes( + public static GeospatialTime queryForCurrentTimes( GeospatialMetadata metaData) throws Exception { GeospatialTime rval = new GeospatialTime(); String areaSource = metaData.getAreaSource().toLowerCase(); @@ -355,12 +380,12 @@ public class GeospatialDataGenerator { StringBuilder sql = new StringBuilder(200); sql.append("SELECT table_name, import_time FROM mapdata.map_version WHERE table_name in ('"); sql.append(areaSource.toLowerCase()); - if (tzSource != null && tzSource.length() > 0) { + if ((tzSource != null) && (tzSource.length() > 0)) { tzSource = tzSource.toLowerCase(); sql.append("', '"); sql.append(tzSource); } - if (pAreaSource != null && pAreaSource.length() > 0) { + if ((pAreaSource != null) && (pAreaSource.length() > 0)) { pAreaSource = pAreaSource.toLowerCase(); sql.append("', '"); sql.append(pAreaSource); @@ -390,7 +415,7 @@ public class GeospatialDataGenerator { return rval; } - private static GeospatialData[] queryGeospatialData(String site, + private GeospatialData[] queryGeospatialData(String site, GeospatialMetadata metaData) throws SpatialException { String areaSource = metaData.getAreaSource(); @@ -423,22 +448,24 @@ public class GeospatialDataGenerator { Geometry clippedGeom = null; for (int i = 0; i < features.length; i++) { multiPolygon = null; - for (int j = 0; j < cwaFeatures.length; j++) { + for (SpatialQueryResult cwaFeature : cwaFeatures) { clippedGeom = features[i].geometry - .intersection(cwaFeatures[j].geometry); + .intersection(cwaFeature.geometry); if (clippedGeom instanceof GeometryCollection) { GeometryCollection gc = (GeometryCollection) clippedGeom; - if (multiPolygon != null) + if (multiPolygon != null) { multiPolygon = multiPolygon .union(convertToMultiPolygon(gc)); - else + } else { multiPolygon = convertToMultiPolygon(gc); + } } } - if (multiPolygon != null) + if (multiPolygon != null) { features[i].geometry = multiPolygon; - else if (clippedGeom != null) + } else if (clippedGeom != null) { features[i].geometry = clippedGeom; + } } } @@ -463,7 +490,7 @@ public class GeospatialDataGenerator { * * @param gc */ - private static MultiPolygon convertToMultiPolygon(GeometryCollection gc) { + private MultiPolygon convertToMultiPolygon(GeometryCollection gc) { GeometryCollectionIterator iter = new GeometryCollectionIterator(gc); Set polygons = new HashSet(); MultiPolygon mp = null; @@ -471,52 +498,59 @@ public class GeospatialDataGenerator { while (iter.hasNext()) { Object o = iter.next(); if (o instanceof MultiPolygon) { - if (mp == null) + if (mp == null) { mp = (MultiPolygon) o; - else + } else { mp = (MultiPolygon) mp.union((MultiPolygon) o); + } } else if (o instanceof Polygon) { polygons.add((Polygon) o); - } else if (o instanceof LineString || o instanceof Point) { + } else if ((o instanceof LineString) || (o instanceof Point)) { LinearRing lr = null; Coordinate[] coords = null; if (o instanceof LineString) { Coordinate[] cs = ((LineString) o).getCoordinates(); if (cs.length < 4) { coords = new Coordinate[4]; - for (int j = 0; j < cs.length; j++) + for (int j = 0; j < cs.length; j++) { coords[j] = new Coordinate(cs[j]); - for (int j = cs.length; j < 4; j++) + } + for (int j = cs.length; j < 4; j++) { coords[j] = new Coordinate(cs[3 - j]); + } } else { coords = new Coordinate[cs.length + 1]; - for (int j = 0; j < cs.length; j++) + for (int j = 0; j < cs.length; j++) { coords[j] = new Coordinate(cs[j]); + } coords[cs.length] = new Coordinate(cs[0]); } } else { coords = new Coordinate[4]; - for (int i = 0; i < 4; i++) + for (int i = 0; i < 4; i++) { coords[i] = ((Point) o).getCoordinate(); + } } lr = (((Geometry) o).getFactory()).createLinearRing(coords); Polygon poly = (new GeometryFactory()).createPolygon(lr, null); - polygons.add((Polygon) poly); + polygons.add(poly); } else { statusHandler.handle(Priority.WARN, "Unprocessed Geometry object: " + o.getClass().getName()); } } - if (mp == null && polygons.size() == 0) + if ((mp == null) && (polygons.size() == 0)) { return null; + } if (polygons.size() > 0) { Polygon[] p = polygons.toArray(new Polygon[0]); - if (mp != null) + if (mp != null) { mp = (MultiPolygon) mp.union(new MultiPolygon(p, gc .getFactory())); - else + } else { mp = new MultiPolygon(p, gc.getFactory()); + } } return mp; } @@ -527,8 +561,7 @@ public class GeospatialDataGenerator { * * @param results */ - private static void topologySimplifyQueryResults( - SpatialQueryResult[] results) { + private void topologySimplifyQueryResults(SpatialQueryResult[] results) { GeometryFactory gf = new GeometryFactory(); Geometry[] geoms = new Geometry[results.length]; for (int i = 0; i < results.length; i++) { @@ -571,7 +604,7 @@ public class GeospatialDataGenerator { * @param hull * @param geoData */ - private static GeospatialData[] queryTimeZones(GeospatialMetadata metaData, + private GeospatialData[] queryTimeZones(GeospatialMetadata metaData, Geometry hull, GeospatialData[] geoData) throws SpatialException { GeospatialData[] rval = null; String timezonePathcastTable = metaData.getTimeZoneSource(); @@ -627,8 +660,8 @@ public class GeospatialDataGenerator { * @return * @throws SpatialException */ - private static GeospatialData[] queryParentAreas( - GeospatialMetadata metaData, Geometry hull) throws SpatialException { + private GeospatialData[] queryParentAreas(GeospatialMetadata metaData, + Geometry hull) throws SpatialException { GeospatialData[] rval = null; String parentAreaSource = metaData.getParentAreaSource(); if (parentAreaSource != null) { @@ -653,7 +686,7 @@ public class GeospatialDataGenerator { return rval; } - private static void persistGeoData(String site, + private void persistGeoData(String site, Map times, GeospatialTime curTime, GeospatialDataSet geoData) throws SerializationException, LocalizationException, JAXBException { @@ -681,7 +714,7 @@ public class GeospatialDataGenerator { lf.write(xml.getBytes()); } - private static void deleteGeomFiles(String site, GeospatialTime time) { + private void deleteGeomFiles(String site, GeospatialTime time) { String fileName = time.getFileName(); IPathManager pathMgr = PathManagerFactory.getPathManager(); @@ -701,8 +734,28 @@ public class GeospatialDataGenerator { } } - private static final String generateGeoDataFilename( - GeospatialMetadata metaData) { + private String generateGeoDataFilename(GeospatialMetadata metaData) { return metaData.getAreaSource() + "_" + metaData.hashCode() + ".bin"; } + + private String getTimeStamp(GeospatialTime curTime, + GeospatialTime lastRunTime) { + long tmStampMs = 0; + if (curTime.getAreaSourceTime() != lastRunTime.getAreaSourceTime()) { + tmStampMs = curTime.getAreaSourceTime(); + } else if (curTime.getParentSourceTime() != lastRunTime + .getParentSourceTime()) { + tmStampMs = curTime.getParentSourceTime(); + } else if (curTime.getTimeZoneSourceTime() != lastRunTime + .getTimeZoneSourceTime()) { + tmStampMs = curTime.getTimeZoneSourceTime(); + } + + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); + sdf.setTimeZone(TimeZone.getTimeZone("GMT")); + Calendar calendar = Calendar.getInstance(); + calendar.setTimeZone(TimeZone.getTimeZone("GMT")); + calendar.setTimeInMillis(tmStampMs); + return sdf.format(calendar.getTime()); + } } diff --git a/edexOsgi/com.raytheon.edex.plugin.warning/src/com/raytheon/edex/plugin/warning/gis/GeospatialDataUpdater.java b/edexOsgi/com.raytheon.edex.plugin.warning/src/com/raytheon/edex/plugin/warning/gis/GeospatialDataUpdater.java deleted file mode 100644 index f32777475d..0000000000 --- a/edexOsgi/com.raytheon.edex.plugin.warning/src/com/raytheon/edex/plugin/warning/gis/GeospatialDataUpdater.java +++ /dev/null @@ -1,140 +0,0 @@ -package com.raytheon.edex.plugin.warning.gis; - -import java.text.SimpleDateFormat; -import java.util.Calendar; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.TimeZone; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import com.raytheon.edex.site.SiteUtil; -import com.raytheon.edex.util.Util; -import com.raytheon.uf.common.dataplugin.warning.config.DialogConfiguration; -import com.raytheon.uf.common.dataplugin.warning.gis.GeospatialFactory; -import com.raytheon.uf.common.dataplugin.warning.gis.GeospatialMetadata; -import com.raytheon.uf.common.dataplugin.warning.gis.GeospatialTime; -import com.raytheon.uf.common.geospatial.SpatialException; -import com.raytheon.uf.common.status.IUFStatusHandler; -import com.raytheon.uf.common.status.UFStatus; -import com.raytheon.uf.common.status.UFStatus.Priority; -import com.raytheon.uf.edex.core.EDEXUtil; -import com.raytheon.uf.edex.core.EdexException; - -/** - * Compares current time in the database against the time of last run - * generated geometry and if they differ regenerates the files. - * - *
- * 
- * SOFTWARE HISTORY
- * 
- * Date         Ticket#    Engineer    Description
- * ------------ ---------- ----------- --------------------------
- * Feb 07, 2014  16090  mgamazaychikov Initial creation
- * 
- * - * @author mgamazaychikov - * @version 1.0 - */ - -public class GeospatialDataUpdater { - private final static IUFStatusHandler statusHandler = UFStatus - .getHandler(GeospatialDataUpdater.class); - private static final String UPDATER_ENDPOINT = "geospatialUpdateNotify"; - private static Log logger = LogFactory.getLog(Util.class); - - private static Set metaDataSet = null; - private static Map map = null; - - public static void runCheckUpdate() throws SpatialException { - StringBuilder sb = new StringBuilder(); - if (metaDataSet == null){ - runInit(); - } - GeospatialTime curTime = null; - GeospatialTime lastRunTime = null; - boolean generate = false; - sb.append("GeospatialDataUpdater: "); - for (GeospatialMetadata md : metaDataSet) { - lastRunTime = map.get(md); - try { - curTime = GeospatialDataGenerator.queryForCurrentTimes(md); - } catch (Exception e) { - throw new SpatialException( - "Unable to look up database version times.", - e); - } - if (!curTime.equals(lastRunTime)) { - generate = true; - break; - } - else { - generate = false; - } - } - if (generate){ - sb.append("Geometry database time differs from current geometry metadata time: regenerating geometries"); - } - else { - return; - } - if (statusHandler.isPriorityEnabled(Priority.INFO)) { - statusHandler.info(sb.toString()); - } - GeospatialDataGenerator.generateUniqueGeospatialMetadataGeometries(); - - String updatedTimeStamp = getTimeStamp(curTime, lastRunTime); - try { - EDEXUtil.getMessageProducer().sendAsync(UPDATER_ENDPOINT, updatedTimeStamp); - } catch (EdexException e) { - logger.error("Could not send message to alarm/alert", e); - } - metaDataSet = null; - } - - private static String getTimeStamp(GeospatialTime curTime, - GeospatialTime lastRunTime) { - long tmStampMs = 0; - if (curTime.getAreaSourceTime() != lastRunTime.getAreaSourceTime()) { - tmStampMs = curTime.getAreaSourceTime(); - } else if (curTime.getParentSourceTime() != lastRunTime.getParentSourceTime()) { - tmStampMs = curTime.getParentSourceTime(); - } else if (curTime.getTimeZoneSourceTime() != lastRunTime.getTimeZoneSourceTime()) { - tmStampMs = curTime.getTimeZoneSourceTime(); - } - - SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); - sdf.setTimeZone(TimeZone.getTimeZone("GMT")); - Calendar calendar = Calendar.getInstance(); - calendar.setTimeZone(TimeZone.getTimeZone("GMT")); - calendar.setTimeInMillis(tmStampMs); - return sdf.format(calendar.getTime()); - } - - private static void runInit() { - String mySite = SiteUtil.getSite(); - DialogConfiguration dialogConfig = null; - - try { - dialogConfig = DialogConfiguration.loadDialogConfig(mySite); - } catch (Exception e) { - statusHandler.handle(Priority.ERROR, - "Error loading warngen config.xml", e); - return; - } - List sites = GeospatialDataGenerator.getBackupSites(dialogConfig); - sites.add(0, mySite); - List templates = GeospatialDataGenerator.getTemplates(dialogConfig); - metaDataSet = GeospatialDataGenerator.getMetaDataSet(sites, templates); - map = GeospatialFactory.loadLastRunGeoTimeSet(mySite); - StringBuilder sb = new StringBuilder(); - if (statusHandler.isPriorityEnabled(Priority.INFO)) { - sb.append("GeospatialDataUpdater has been re-inited"); - statusHandler.info(sb.toString()); - } - } - -} diff --git a/edexOsgi/com.raytheon.edex.rpgenvdata/res/spring/rpgenvdata-spring.xml b/edexOsgi/com.raytheon.edex.rpgenvdata/res/spring/rpgenvdata-spring.xml index ea6bff1198..a7b6d0cd84 100644 --- a/edexOsgi/com.raytheon.edex.rpgenvdata/res/spring/rpgenvdata-spring.xml +++ b/edexOsgi/com.raytheon.edex.rpgenvdata/res/spring/rpgenvdata-spring.xml @@ -33,7 +33,7 @@
- + diff --git a/edexOsgi/com.raytheon.edex.textdb/res/spring/textdb-ingest.xml b/edexOsgi/com.raytheon.edex.textdb/res/spring/textdb-ingest.xml index d447a300cc..ca6c7af184 100644 --- a/edexOsgi/com.raytheon.edex.textdb/res/spring/textdb-ingest.xml +++ b/edexOsgi/com.raytheon.edex.textdb/res/spring/textdb-ingest.xml @@ -5,7 +5,6 @@ - diff --git a/edexOsgi/com.raytheon.edex.utilitysrv/res/spring/utility-request.xml b/edexOsgi/com.raytheon.edex.utilitysrv/res/spring/utility-request.xml index 2639e15829..2388a9a6c0 100644 --- a/edexOsgi/com.raytheon.edex.utilitysrv/res/spring/utility-request.xml +++ b/edexOsgi/com.raytheon.edex.utilitysrv/res/spring/utility-request.xml @@ -37,7 +37,7 @@ - + diff --git a/edexOsgi/com.raytheon.uf.common.dataplugin/META-INF/MANIFEST.MF b/edexOsgi/com.raytheon.uf.common.dataplugin/META-INF/MANIFEST.MF index 7528d681f3..f9d11b5733 100644 --- a/edexOsgi/com.raytheon.uf.common.dataplugin/META-INF/MANIFEST.MF +++ b/edexOsgi/com.raytheon.uf.common.dataplugin/META-INF/MANIFEST.MF @@ -8,7 +8,6 @@ Bundle-RequiredExecutionEnvironment: JavaSE-1.6 Eclipse-RegisterBuddy: com.raytheon.uf.common.serialization Export-Package: com.raytheon.uf.common.dataplugin, com.raytheon.uf.common.dataplugin.annotations, - com.raytheon.uf.common.dataplugin.defaults, com.raytheon.uf.common.dataplugin.exception, com.raytheon.uf.common.dataplugin.message, com.raytheon.uf.common.dataplugin.persist, diff --git a/edexOsgi/com.raytheon.uf.common.dataplugin/src/com/raytheon/uf/common/dataplugin/PluginProperties.java b/edexOsgi/com.raytheon.uf.common.dataplugin/src/com/raytheon/uf/common/dataplugin/PluginProperties.java index 5855566dba..70f6738b6c 100644 --- a/edexOsgi/com.raytheon.uf.common.dataplugin/src/com/raytheon/uf/common/dataplugin/PluginProperties.java +++ b/edexOsgi/com.raytheon.uf.common.dataplugin/src/com/raytheon/uf/common/dataplugin/PluginProperties.java @@ -21,7 +21,6 @@ package com.raytheon.uf.common.dataplugin; import java.util.List; -import com.raytheon.uf.common.dataplugin.defaults.PluginPropertyDefaults; import com.raytheon.uf.common.dataplugin.persist.IHDFFilePathProvider; /** @@ -32,8 +31,8 @@ import com.raytheon.uf.common.dataplugin.persist.IHDFFilePathProvider; * SOFTWARE HISTORY * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- - * Mar 20, 2009 njensen Initial creation - * + * Mar 20, 2009 njensen Initial creation. + * Mar 13, 2014 2726 rjpeter Moved default values to set on plugin registration. * * * @author njensen @@ -54,7 +53,7 @@ public class PluginProperties { protected Class record; - protected int initialRetentionTime; + protected Integer initialRetentionTime; protected String pluginFQN; @@ -62,22 +61,40 @@ public class PluginProperties { protected IHDFFilePathProvider pathProvider; + /** + * Set the defaults for any fields that haven't already been set to a not + * null value. + * + * @param defaults + */ + public void setDefaults(PluginProperties defaults) { + /* + * pluginName, pluginFQN, dependencyFQNs, and record have no defaults to + * inherit + */ + + if (database == null) { + database = defaults.getDatabase(); + } + if (initializer == null) { + initializer = defaults.getInitializer(); + } + if (dao == null) { + dao = defaults.getDao(); + } + if (initialRetentionTime == null) { + initialRetentionTime = defaults.getInitialRetentionTime(); + } + if (pathProvider == null) { + pathProvider = defaults.getPathProvider(); + } + } + /** * Compression to use on storage, if null, no compression */ protected String compression; - /** - * Constructor that initializes values to default values - */ - public PluginProperties() { - database = PluginPropertyDefaults.getDatabase(); - initializer = PluginPropertyDefaults.getInitializer(); - dao = PluginPropertyDefaults.getDao(); - initialRetentionTime = PluginPropertyDefaults.getInitialRetentionTime(); - pathProvider = PluginPropertyDefaults.getPathProvider(); - } - /** * @return the database */ @@ -112,7 +129,11 @@ public class PluginProperties { * @return the initialRetentionTime */ public int getInitialRetentionTime() { - return initialRetentionTime; + if (initialRetentionTime != null) { + return initialRetentionTime; + } + + return 0; } /** @@ -199,5 +220,4 @@ public class PluginProperties { public void setCompression(String compression) { this.compression = compression; } - } diff --git a/edexOsgi/com.raytheon.uf.common.dataplugin/src/com/raytheon/uf/common/dataplugin/defaults/PluginPropertyDefaults.java b/edexOsgi/com.raytheon.uf.common.dataplugin/src/com/raytheon/uf/common/dataplugin/defaults/PluginPropertyDefaults.java deleted file mode 100644 index 92dcc50e22..0000000000 --- a/edexOsgi/com.raytheon.uf.common.dataplugin/src/com/raytheon/uf/common/dataplugin/defaults/PluginPropertyDefaults.java +++ /dev/null @@ -1,120 +0,0 @@ -/** - * 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.common.dataplugin.defaults; - -import com.raytheon.uf.common.dataplugin.persist.IHDFFilePathProvider; - -/** - * Defaults for the data plugins. Setters should only be called once through - * Spring XML configuration. - * - *
- * 
- * SOFTWARE HISTORY
- * Date         Ticket#    Engineer    Description
- * ------------ ---------- ----------- --------------------------
- * Mar 20, 2009            njensen     Initial creation
- * 
- * 
- * - * @author njensen - * @version 1.0 - */ - -public class PluginPropertyDefaults { - - protected static String database; - - protected static Class initializer; - - protected static Class dao; - - protected static int initialRetentionTime; - - protected static IHDFFilePathProvider pathProvider; - - /** - * @return the database - */ - public static String getDatabase() { - return database; - } - - /** - * @param database - * the database to set - */ - public void setDatabase(String database) { - PluginPropertyDefaults.database = database; - } - - /** - * @return the initialRetentionTime - */ - public static int getInitialRetentionTime() { - return initialRetentionTime; - } - - /** - * @param initialRetentionTime - * the initialRetentionTime to set - */ - public void setInitialRetentionTime(int initialRetentionTime) { - PluginPropertyDefaults.initialRetentionTime = initialRetentionTime; - } - - /** - * @return the initializer - */ - public static Class getInitializer() { - return initializer; - } - - /** - * @param initializer - * the initializer to set - */ - public void setInitializer(Class initializer) { - PluginPropertyDefaults.initializer = initializer; - } - - /** - * @return the dao - */ - public static Class getDao() { - return dao; - } - - /** - * @param dao - * the dao to set - */ - public void setDao(Class dao) { - PluginPropertyDefaults.dao = dao; - } - - public static IHDFFilePathProvider getPathProvider() { - return pathProvider; - } - - public void setPathProvider(IHDFFilePathProvider pathProvider) { - PluginPropertyDefaults.pathProvider = pathProvider; - } -} diff --git a/edexOsgi/com.raytheon.uf.common.message/META-INF/MANIFEST.MF b/edexOsgi/com.raytheon.uf.common.message/META-INF/MANIFEST.MF index 955d1c0a0c..52565ea439 100644 --- a/edexOsgi/com.raytheon.uf.common.message/META-INF/MANIFEST.MF +++ b/edexOsgi/com.raytheon.uf.common.message/META-INF/MANIFEST.MF @@ -13,4 +13,5 @@ Import-Package: com.raytheon.uf.common.serialization, com.raytheon.uf.common.serialization.annotations, org.apache.commons.lang Require-Bundle: net.sf.cglib;bundle-version="2.1.3", - com.raytheon.uf.common.status;bundle-version="1.11.11" + com.raytheon.uf.common.status;bundle-version="1.11.11", + com.raytheon.uf.common.util diff --git a/edexOsgi/com.raytheon.uf.common.message/src/com/raytheon/uf/common/message/WsId.java b/edexOsgi/com.raytheon.uf.common.message/src/com/raytheon/uf/common/message/WsId.java index 2a2a279cc2..bade300b25 100644 --- a/edexOsgi/com.raytheon.uf.common.message/src/com/raytheon/uf/common/message/WsId.java +++ b/edexOsgi/com.raytheon.uf.common.message/src/com/raytheon/uf/common/message/WsId.java @@ -20,18 +20,13 @@ package com.raytheon.uf.common.message; import java.io.Serializable; -import java.lang.management.ManagementFactory; import java.net.InetAddress; -import java.net.UnknownHostException; -import java.util.Collections; -import java.util.LinkedHashMap; -import java.util.Map; -import java.util.Map.Entry; import com.raytheon.uf.common.message.adapter.WsIdAdapter; import com.raytheon.uf.common.serialization.ISerializableObject; import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; import com.raytheon.uf.common.serialization.annotations.DynamicSerializeTypeAdapter; +import com.raytheon.uf.common.util.SystemUtil; /** * The WsId contains the work station identification for the user. * @@ -41,12 +36,12 @@ import com.raytheon.uf.common.serialization.annotations.DynamicSerializeTypeAdap * SOFTWARE HISTORY * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- - * Jun 10, 2009 randerso Initial creation - * Apr 25, 2012 545 randerso Repurposed the lockKey field as threadId - * Sep 19, 2012 #1190 dgilling Cache host names so toPrettyString() doesn't - * get delayed behind DNS requests. - * Sep 20, 2012 #1190 dgilling Create method getHostName(). - * + * Jun 10, 2009 randerso Initial creation + * Apr 25, 2012 545 randerso Repurposed the lockKey field as threadId + * Sep 19, 2012 #1190 dgilling Cache host names so toPrettyString() doesn't + * get delayed behind DNS requests. + * Sep 20, 2012 #1190 dgilling Create method getHostName(). + * Mar 20, 2014 2726 rjpeter Moved hostNameCache to SystemUtil. * * * @author randerso @@ -57,32 +52,8 @@ import com.raytheon.uf.common.serialization.annotations.DynamicSerializeTypeAdap @DynamicSerializeTypeAdapter(factory = WsIdAdapter.class) public class WsId implements Serializable, ISerializableObject { - private static class BoundedMap extends LinkedHashMap { - private static final long serialVersionUID = 1L; - - private final int maxSize; - - public BoundedMap(int maxSize) { - super(16, 0.75f, true); - this.maxSize = maxSize; - } - - /* - * (non-Javadoc) - * - * @see java.util.LinkedHashMap#removeEldestEntry(java.util.Map.Entry) - */ - @Override - protected boolean removeEldestEntry(Entry eldest) { - return size() > maxSize; - } - } - private static final long serialVersionUID = 1L; - private static final Map hostNameCache = Collections - .synchronizedMap(new BoundedMap(100)); - private final InetAddress networkId; private final String userName; @@ -169,25 +140,14 @@ public class WsId implements Serializable, ISerializableObject { this.progName = "unknown"; } - this.pid = Integer.parseInt(ManagementFactory.getRuntimeMXBean() - .getName().split("@")[0]); + this.pid = SystemUtil.getPid(); this.threadId = Thread.currentThread().getId(); if (networkId != null) { this.networkId = networkId; } else { - InetAddress addr = null; - try { - addr = InetAddress.getLocalHost(); - } catch (UnknownHostException e) { - try { - addr = InetAddress.getByAddress(new byte[] { 0, 0, 0, 0 }); - } catch (UnknownHostException e1) { - // won't happen - } - } - this.networkId = addr; + this.networkId = SystemUtil.getLocalAddress(); } } @@ -203,7 +163,7 @@ public class WsId implements Serializable, ISerializableObject { long addr = 0; byte[] bytes = networkId.getAddress(); for (int i = bytes.length - 1; i >= 0; i--) { - addr = addr << 8 | (0xff & bytes[i]); + addr = (addr << 8) | (0xff & bytes[i]); } o.append(addr).append(':').append(userName).append(':') @@ -219,7 +179,7 @@ public class WsId implements Serializable, ISerializableObject { * @return WsId as pretty string */ public String toPrettyString() { - String hostname = retrieveFromHostCache(networkId); + String hostname = SystemUtil.getHostName(networkId); StringBuilder o = new StringBuilder(); o.append(userName).append('@').append(hostname).append(':') @@ -229,16 +189,6 @@ public class WsId implements Serializable, ISerializableObject { return o.toString(); } - private String retrieveFromHostCache(InetAddress address) { - String hostName = hostNameCache.get(address); - if (hostName == null) { - hostName = address.getHostName(); - hostNameCache.put(address, hostName); - } - - return hostName; - } - /** * @return the _networkId */ @@ -247,7 +197,7 @@ public class WsId implements Serializable, ISerializableObject { } public String getHostName() { - return retrieveFromHostCache(networkId); + return SystemUtil.getHostName(networkId); } /** @@ -287,13 +237,13 @@ public class WsId implements Serializable, ISerializableObject { public int hashCode() { final int prime = 31; int result = 1; - result = prime * result + (int) (threadId ^ (threadId >>> 32)); - result = prime * result + result = (prime * result) + (int) (threadId ^ (threadId >>> 32)); + result = (prime * result) + ((networkId == null) ? 0 : networkId.hashCode()); - result = prime * result + pid; - result = prime * result + result = (prime * result) + pid; + result = (prime * result) + ((progName == null) ? 0 : progName.hashCode()); - result = prime * result + result = (prime * result) + ((userName == null) ? 0 : userName.hashCode()); return result; } diff --git a/edexOsgi/com.raytheon.uf.common.util/src/com/raytheon/uf/common/util/SystemUtil.java b/edexOsgi/com.raytheon.uf.common.util/src/com/raytheon/uf/common/util/SystemUtil.java index f1a5903d74..a113752e68 100644 --- a/edexOsgi/com.raytheon.uf.common.util/src/com/raytheon/uf/common/util/SystemUtil.java +++ b/edexOsgi/com.raytheon.uf.common.util/src/com/raytheon/uf/common/util/SystemUtil.java @@ -21,9 +21,11 @@ package com.raytheon.uf.common.util; import java.lang.management.ManagementFactory; import java.net.InetAddress; -import java.net.NetworkInterface; -import java.net.SocketException; -import java.util.Enumeration; +import java.net.UnknownHostException; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Map.Entry; /** * System utilities such as hostname and pid lookup. @@ -35,18 +37,57 @@ import java.util.Enumeration; * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- * Sep 26, 2011 rjpeter Initial creation - * + * Apr 10, 2014 2726 rjpeter Moved hostName caching logic from WsId to here. * * * @author rjpeter * @version 1.0 */ - public class SystemUtil { + /** + * Map that can be limited to a given number of entries. + */ + private static class BoundedMap extends LinkedHashMap { + private static final long serialVersionUID = 1L; + + private final int maxSize; + + public BoundedMap(int maxSize) { + super(16, 0.75f, true); + this.maxSize = maxSize; + } + + /* + * (non-Javadoc) + * + * @see java.util.LinkedHashMap#removeEldestEntry(java.util.Map.Entry) + */ + @Override + protected boolean removeEldestEntry(Entry eldest) { + return size() > maxSize; + } + } + + private static final Map hostNameCache = Collections + .synchronizedMap(new BoundedMap(100)); + protected static String hostName; protected static Integer pid; + protected static InetAddress addr; + + static { + /* attempt to initialize fields */ + getPid(); + getHostName(); + } + + /** + * Returns the pid of the current process. + * + * @return + */ public static int getPid() { if (pid == null) { pid = new Integer(ManagementFactory.getRuntimeMXBean().getName() @@ -56,43 +97,65 @@ public class SystemUtil { return pid.intValue(); } + /** + * Returns the local INetAddress. + * + * @return + */ + public static InetAddress getLocalAddress() { + if (addr == null) { + try { + addr = InetAddress.getLocalHost(); + } catch (UnknownHostException e) { + try { + return InetAddress.getByAddress(new byte[] { 0, 0, 0, 0 }); + } catch (UnknownHostException e1) { + // won't happen + } + } + } + return addr; + } + + /** + * Returns the hostName for the given inet address. The address is cached + * for the lifetime of the jvm after first look up. If a machine changes IPs + * it will get mapped to the wrong hostName until a reboot. + * + * @param address + * @return + */ + public static String getHostName(InetAddress address) { + String hostName = hostNameCache.get(address); + if (hostName == null) { + hostName = address.getHostName(); + hostNameCache.put(address, hostName); + } + + return hostName; + } + + /** + * Returns local host name. + * + * @return + */ public static String getHostName() { if (hostName == null) { - InetAddress addrToUse = null; - boolean found = false; - try { - Enumeration nis = NetworkInterface - .getNetworkInterfaces(); - while (nis.hasMoreElements() && !found) { - NetworkInterface ni = nis.nextElement(); - ni.isVirtual(); - ni.isUp(); - Enumeration addrs = ni.getInetAddresses(); - while (addrs.hasMoreElements() && !found) { - InetAddress addr = addrs.nextElement(); - if (addr.isLinkLocalAddress() == false - && addr.isSiteLocalAddress() == false - && addr.isLoopbackAddress() == false) { - addrToUse = addr; - found = true; - } - } - } - } catch (SocketException e) { - e.printStackTrace(); - } + InetAddress addr = getLocalAddress(); + hostName = getHostName(addr); - if (addrToUse == null) { + if (hostName == null) { String hostNameProp = System.getenv("HOSTNAME"); - if (hostNameProp != null && hostNameProp.trim().length() == 0) { + if ((hostNameProp != null) + && (hostNameProp.trim().length() == 0)) { hostName = hostNameProp; } else { hostName = "localhost"; } - } else { - hostName = addrToUse.getHostName(); } } + return hostName; } } diff --git a/edexOsgi/com.raytheon.uf.edex.activetable/res/spring/activetable-ingest.xml b/edexOsgi/com.raytheon.uf.edex.activetable/res/spring/activetable-ingest.xml index 434c097ac8..1a9ee5f976 100644 --- a/edexOsgi/com.raytheon.uf.edex.activetable/res/spring/activetable-ingest.xml +++ b/edexOsgi/com.raytheon.uf.edex.activetable/res/spring/activetable-ingest.xml @@ -1,14 +1,11 @@ + http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd"> + errorHandlerRef="errorHandler"> @@ -37,8 +34,7 @@ - + \ No newline at end of file diff --git a/edexOsgi/com.raytheon.uf.edex.activetable/res/spring/activetable-request.xml b/edexOsgi/com.raytheon.uf.edex.activetable/res/spring/activetable-request.xml index de0604e03e..a5e9dd59a7 100644 --- a/edexOsgi/com.raytheon.uf.edex.activetable/res/spring/activetable-request.xml +++ b/edexOsgi/com.raytheon.uf.edex.activetable/res/spring/activetable-request.xml @@ -89,7 +89,7 @@ + errorHandlerRef="errorHandler"> @@ -102,8 +102,7 @@ - + \ No newline at end of file diff --git a/edexOsgi/com.raytheon.uf.edex.core/src/com/raytheon/uf/edex/core/EDEXUtil.java b/edexOsgi/com.raytheon.uf.edex.core/src/com/raytheon/uf/edex/core/EDEXUtil.java index 5def363804..e7680772f8 100644 --- a/edexOsgi/com.raytheon.uf.edex.core/src/com/raytheon/uf/edex/core/EDEXUtil.java +++ b/edexOsgi/com.raytheon.uf.edex.core/src/com/raytheon/uf/edex/core/EDEXUtil.java @@ -22,9 +22,7 @@ package com.raytheon.uf.edex.core; import java.io.File; import java.io.IOException; -import java.net.InetAddress; import java.net.URL; -import java.net.UnknownHostException; import java.util.Calendar; import java.util.Date; import java.util.TimeZone; @@ -52,12 +50,13 @@ import com.raytheon.uf.edex.core.props.PropertiesFactory; * SOFTWARE HISTORY * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- - * 04/23/08 1088 chammack Split from Util + * 04/23/2008 1088 chammack Split from Util * 11/22/2010 2235 cjeanbap Added audio file to StatusMessage. * 02/02/2011 6500 cjeanbap Added paramter to method signature and * properly assign source value. * 06/12/2012 0609 djohnson Use EDEXUtil for EDEX_HOME. - * 3/18/2013 1802 bphillip Added getList utility function + * 03/18/2013 1802 bphillip Added getList utility function + * 04/10/2014 2726 rjpeter Added methods for waiting for edex to be running. * * * @author chammack @@ -81,20 +80,7 @@ public class EDEXUtil implements ApplicationContextAware { // TODO private static final String alertEndpoint = "alertVizNotify"; - private static int serverId; - static { - try { - String hostname = InetAddress.getLocalHost().getCanonicalHostName(); - serverId = hostname.hashCode(); - } catch (UnknownHostException e) { - serverId = 0; - // assume localhost, no network connection - } - } - - public static int getServerId() { - return serverId; - } + private static final Object waiter = new Object(); @Override public void setApplicationContext(ApplicationContext context) @@ -146,6 +132,30 @@ public class EDEXUtil implements ApplicationContextAware { return "Operational".equals(System.getProperty("System.status")); } + /** + * Blocks until EDEX is in the running state. + */ + public static void waitForRunning() { + synchronized (waiter) { + try { + while (!isRunning()) { + waiter.wait(15000); + } + } catch (InterruptedException e) { + // ignore + } + } + } + + /** + * Called once EDEX is in a running state to notify all waiting clients. + */ + public static void notifyIsRunning() { + synchronized (waiter) { + waiter.notifyAll(); + } + } + public static boolean containsESBComponent(String name) { return CONTEXT.containsBean(name); } @@ -176,9 +186,10 @@ public class EDEXUtil implements ApplicationContextAware { persistDir = envProperties.getEnvValue("PERSISTDIR"); persistDir = FileUtil.convertFilePath(persistDir); - if (persistDir == null) + if (persistDir == null) { throw new PluginException( "Unable to retrieve value for the PERSISTDIR"); + } dbDirectory = new File(persistDir); dbDirectory.mkdirs(); diff --git a/edexOsgi/com.raytheon.uf.edex.core/src/com/raytheon/uf/edex/core/EdexTimerBasedThread.java b/edexOsgi/com.raytheon.uf.edex.core/src/com/raytheon/uf/edex/core/EdexTimerBasedThread.java new file mode 100644 index 0000000000..ecc24dcd00 --- /dev/null +++ b/edexOsgi/com.raytheon.uf.edex.core/src/com/raytheon/uf/edex/core/EdexTimerBasedThread.java @@ -0,0 +1,172 @@ +/** + * 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.core; + +import java.util.LinkedList; +import java.util.List; +import java.util.concurrent.atomic.AtomicInteger; + +import com.raytheon.uf.common.status.IUFStatusHandler; +import com.raytheon.uf.common.status.UFStatus; + +/** + * Base class for Timer based threading. Allows previous thread based paradigms + * to hook in to a camel context with minimal work. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Mar 19, 2014 2826       rjpeter     Initial creation.
+ * 
+ * 
+ * + * @author rjpeter + * @version 1.0 + */ +public abstract class EdexTimerBasedThread implements IContextStateProcessor { + /** + * Number of threads that have been started. + */ + protected final AtomicInteger threadCount = new AtomicInteger(0); + + /** + * Current active threads. + */ + protected final List threads = new LinkedList(); + + /** + * Whether the container is running or not. + */ + protected volatile boolean running = true; + + /** + * Interval thread should sleep between calls. + */ + protected int threadSleepInterval = 30000; + + /** + * The name to use for the threads. + * + * @return + */ + public abstract String getThreadGroupName(); + + /** + * Method to do the work. Should return when done. Run method handles start + * up/shutdown mechanism. + * + * @throws Exception + */ + public abstract void process() throws Exception; + + /** + * Can be overridden to do any work to cleanup the thread on shutdown. + */ + public void dispose() { + + } + + /** + * Called by camel to do the processing. Will run until the context is + * shutdown. + */ + public void run() { + synchronized (threads) { + threads.add(Thread.currentThread()); + } + + try { + Thread.currentThread().setName( + getThreadGroupName() + "-" + threadCount.incrementAndGet()); + + while (running) { + try { + process(); + } catch (Exception e) { + UFStatus.getHandler().error( + "Error occurred during processing", e); + } + + try { + /* + * use waiter to allow shutdown to wake thread for immediate + * shutdown + */ + synchronized (threads) { + threads.wait(threadSleepInterval); + } + } catch (InterruptedException e) { + // ignore + } + } + } finally { + synchronized (threads) { + threads.remove(Thread.currentThread()); + threads.notify(); + } + dispose(); + } + } + + @Override + public void preStart() { + } + + @Override + public void postStart() { + } + + @Override + public void preStop() { + running = false; + synchronized (threads) { + threads.notifyAll(); + } + } + + @Override + public void postStop() { + IUFStatusHandler statusHandler = UFStatus.getHandler(); + String msg = "Waiting for " + getThreadGroupName() + + " threads to finish"; + + synchronized (threads) { + while (!threads.isEmpty()) { + statusHandler.info(msg); + try { + threads.wait(10000); + } catch (Exception e) { + // ignore + } + } + } + } + + public int getThreadSleepInterval() { + return threadSleepInterval; + } + + public void setThreadSleepInterval(int threadSleepInterval) { + this.threadSleepInterval = threadSleepInterval; + } +} diff --git a/edexOsgi/com.raytheon.edex.plugin.warning/src/com/raytheon/edex/plugin/warning/gis/GeospatialDataGeneratorThread.java b/edexOsgi/com.raytheon.uf.edex.core/src/com/raytheon/uf/edex/core/IContextStateProcessor.java similarity index 53% rename from edexOsgi/com.raytheon.edex.plugin.warning/src/com/raytheon/edex/plugin/warning/gis/GeospatialDataGeneratorThread.java rename to edexOsgi/com.raytheon.uf.edex.core/src/com/raytheon/uf/edex/core/IContextStateProcessor.java index 4bcb51188c..fe0e5af288 100644 --- a/edexOsgi/com.raytheon.edex.plugin.warning/src/com/raytheon/edex/plugin/warning/gis/GeospatialDataGeneratorThread.java +++ b/edexOsgi/com.raytheon.uf.edex.core/src/com/raytheon/uf/edex/core/IContextStateProcessor.java @@ -17,10 +17,11 @@ * See the AWIPS II Master Rights File ("Master Rights File.pdf") for * further licensing information. **/ -package com.raytheon.edex.plugin.warning.gis; +package com.raytheon.uf.edex.core; /** - * TODO Add Description + * Methods to be called as part of the context life cycle for starting and + * stopping the context. * *
  * 
@@ -28,31 +29,36 @@ package com.raytheon.edex.plugin.warning.gis;
  * 
  * Date         Ticket#    Engineer    Description
  * ------------ ---------- ----------- --------------------------
- * Jul 24, 2011            rjpeter     Initial creation
+ * Feb 26, 2014 2726       rjpeter     Initial creation
  * 
  * 
* * @author rjpeter * @version 1.0 */ +public interface IContextStateProcessor { -public class GeospatialDataGeneratorThread { - public GeospatialDataGeneratorThread() { - Thread t = new Thread("WarngenGeometryGenerator") { - public void run() { - // TODO: Move to camel timer, when camel upgraded to at least - // 2.8 and take advantage of single run timer - try { - // delay to allow server to start - Thread.sleep(120000); - } catch (InterruptedException e) { - // ignore - } - GeospatialDataGenerator - .generateUniqueGeospatialMetadataGeometries(); - // scan and clean old geometries - } - }; - t.start(); - } + /** + * Perform any work that needs to be done before the context is started, + * such as initialization. + */ + public void preStart(); + + /** + * Perform any work that needs to be done after the context is started, such + * as sending notifications to clients. + */ + public void postStart(); + + /** + * Perform any work that needs to be done before context is stopped, such as + * notifying async threads to stop. + */ + public void preStop(); + + /** + * Perform any work that needs to be done after the context is stopped, such + * as sending in memory data. + */ + public void postStop(); } diff --git a/edexOsgi/com.raytheon.uf.edex.core/src/com/raytheon/uf/edex/core/dataplugin/PluginRegistry.java b/edexOsgi/com.raytheon.uf.edex.core/src/com/raytheon/uf/edex/core/dataplugin/PluginRegistry.java index 5b1d410f0a..ade941c9aa 100644 --- a/edexOsgi/com.raytheon.uf.edex.core/src/com/raytheon/uf/edex/core/dataplugin/PluginRegistry.java +++ b/edexOsgi/com.raytheon.uf.edex.core/src/com/raytheon/uf/edex/core/dataplugin/PluginRegistry.java @@ -35,8 +35,8 @@ import com.raytheon.uf.common.util.registry.RegistryException; * SOFTWARE HISTORY * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- - * Aug 6, 2009 mschenke Initial creation - * + * Aug 6, 2009 mschenke Initial creation. + * Mar 19, 2014 2726 rjpeter Updated for graceful shutdown and easier spring dependency management. * * * @author mschenke @@ -47,7 +47,15 @@ public class PluginRegistry extends GenericRegistry { private static PluginRegistry instance = new PluginRegistry(); - private List listeners = new ArrayList(); + /** + * Plugin registry listeners. + */ + private final List listeners = new ArrayList(); + + /** + * Default values for plugins registered with the registry. + */ + private PluginProperties defaultPluginProperties; private PluginRegistry() { super(); @@ -61,6 +69,8 @@ public class PluginRegistry extends GenericRegistry { public Object register(String pluginName, PluginProperties pluginProperties) throws RegistryException { if (!registry.containsKey(pluginName)) { + pluginProperties.setDefaults(defaultPluginProperties); + super.register(pluginName, pluginProperties); for (IPluginRegistryChanged iprc : listeners) { iprc.pluginAdded(pluginName); @@ -77,4 +87,22 @@ public class PluginRegistry extends GenericRegistry { return this; } + public PluginProperties getDefaultPluginProperties() { + return defaultPluginProperties; + } + + public void setDefaultPluginProperties( + PluginProperties defaultPluginProperties) { + this.defaultPluginProperties = defaultPluginProperties; + } + + /** + * The initial listeners to the plugin registry to ensure minimum + * requirements are meant via spring launching. + * + * @param listeners + */ + public void setInitialListeners(List listeners) { + this.listeners.addAll(listeners); + } } diff --git a/edexOsgi/com.raytheon.uf.edex.cpgsrv/res/spring/cpgsrv-spring.xml b/edexOsgi/com.raytheon.uf.edex.cpgsrv/res/spring/cpgsrv-spring.xml index c1dd697082..bcc6a25751 100644 --- a/edexOsgi/com.raytheon.uf.edex.cpgsrv/res/spring/cpgsrv-spring.xml +++ b/edexOsgi/com.raytheon.uf.edex.cpgsrv/res/spring/cpgsrv-spring.xml @@ -4,16 +4,10 @@ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd"> - - - - + errorHandlerRef="errorHandler"> @@ -21,8 +15,7 @@ + errorHandlerRef="errorHandler"> @@ -38,8 +31,7 @@ - + diff --git a/edexOsgi/com.raytheon.uf.edex.database/res/spring/database-common.xml b/edexOsgi/com.raytheon.uf.edex.database/res/spring/database-common.xml index 993ed67877..f8eb24d779 100644 --- a/edexOsgi/com.raytheon.uf.edex.database/res/spring/database-common.xml +++ b/edexOsgi/com.raytheon.uf.edex.database/res/spring/database-common.xml @@ -49,7 +49,9 @@ - + + + diff --git a/edexOsgi/com.raytheon.uf.edex.database/src/com/raytheon/uf/edex/database/DatabasePluginRegistry.java b/edexOsgi/com.raytheon.uf.edex.database/src/com/raytheon/uf/edex/database/DatabasePluginRegistry.java index 0ce6efef40..79dff30c5d 100644 --- a/edexOsgi/com.raytheon.uf.edex.database/src/com/raytheon/uf/edex/database/DatabasePluginRegistry.java +++ b/edexOsgi/com.raytheon.uf.edex.database/src/com/raytheon/uf/edex/database/DatabasePluginRegistry.java @@ -40,8 +40,8 @@ import com.raytheon.uf.edex.core.dataplugin.PluginRegistry; * SOFTWARE HISTORY * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- - * Apr 28, 2010 #5050 rjpeter Initial creation - * + * Apr 28, 2010 #5050 rjpeter Initial creation + * May 29, 2014 2726 rjpeter Added initial listeners and properties for easier spring dependency management. * * * @author rjpeter @@ -56,7 +56,9 @@ public class DatabasePluginRegistry extends private static DatabasePluginRegistry instance = new DatabasePluginRegistry(); - private List listeners = new ArrayList(); + private final List listeners = new ArrayList(); + + private List initialProperties; private DatabasePluginRegistry() { super(); @@ -66,6 +68,18 @@ public class DatabasePluginRegistry extends return instance; } + /** + * Called by spring to initialize the registry. Mainly used to ensure the + * base database plugin is always loaded. + */ + public void init() throws RegistryException { + if ((initialProperties != null) && !initialProperties.isEmpty()) { + for (DatabasePluginProperties dbProp : initialProperties) { + register(dbProp.getPluginFQN(), dbProp); + } + } + } + @Override public Object register(String pluginFQN, DatabasePluginProperties pluginProperties) throws RegistryException { @@ -95,7 +109,8 @@ public class DatabasePluginRegistry extends public void pluginAdded(String pluginName) { PluginProperties props = PluginRegistry.getInstance() .getRegisteredObject(pluginName); - if (props.getPluginFQN() != null && props.getPluginFQN().length() > 0) { + if ((props.getPluginFQN() != null) + && (props.getPluginFQN().length() > 0)) { // multiple plugins may use the same jar file. if (!registry.containsKey(props.getPluginFQN())) { try { @@ -109,4 +124,14 @@ public class DatabasePluginRegistry extends } } } + + public void setInitialListeners( + List listeners) { + this.listeners.addAll(listeners); + } + + public void setInitialProperties( + List initialProperties) { + this.initialProperties = initialProperties; + } } diff --git a/edexOsgi/com.raytheon.uf.edex.database/src/com/raytheon/uf/edex/database/plugin/PluginFactory.java b/edexOsgi/com.raytheon.uf.edex.database/src/com/raytheon/uf/edex/database/plugin/PluginFactory.java index fb3024071d..cfe5243eab 100644 --- a/edexOsgi/com.raytheon.uf.edex.database/src/com/raytheon/uf/edex/database/plugin/PluginFactory.java +++ b/edexOsgi/com.raytheon.uf.edex.database/src/com/raytheon/uf/edex/database/plugin/PluginFactory.java @@ -31,7 +31,6 @@ import com.raytheon.uf.common.dataplugin.IPluginClassMapper; import com.raytheon.uf.common.dataplugin.PluginDataObject; import com.raytheon.uf.common.dataplugin.PluginException; import com.raytheon.uf.common.dataplugin.PluginProperties; -import com.raytheon.uf.common.dataplugin.defaults.PluginPropertyDefaults; import com.raytheon.uf.common.dataplugin.persist.IHDFFilePathProvider; import com.raytheon.uf.edex.core.dataplugin.PluginRegistry; @@ -50,7 +49,7 @@ import com.raytheon.uf.edex.core.dataplugin.PluginRegistry; * Feb 06, 2009 1990 bphillip Refactored to use spring container * Mar 20, 2009 njensen Refactored to use PluginProperties * May 16, 2013 1869 bsteffen Rewrite dataURI property mappings. - * + * Mar 19, 2014 2726 rjpeter Added defaultPathProvider field. * * * @author garmendariz @@ -75,7 +74,9 @@ public class PluginFactory implements IPluginClassMapper { private Map pluginDaoMap = new HashMap(); - private Object daoMapLock = new Object(); + private final Object daoMapLock = new Object(); + + private IHDFFilePathProvider defaultPathProvider = null; /** * Private constructor @@ -173,6 +174,7 @@ public class PluginFactory implements IPluginClassMapper { * @throws PluginException * If the class cannot be determined */ + @Override public Class getPluginRecordClass(String pluginName) throws PluginException { PluginProperties props = PluginRegistry.getInstance() @@ -233,7 +235,7 @@ public class PluginFactory implements IPluginClassMapper { if (props != null) { rval = props.getPathProvider(); } else { - rval = PluginPropertyDefaults.getPathProvider(); + rval = defaultPathProvider; } return rval; } @@ -280,4 +282,13 @@ public class PluginFactory implements IPluginClassMapper { + " is not registered with the PluginRegistry"); } } + + /** + * Set the default path provider. Used by spring to configure the factory. + * + * @param defaultPathProvider + */ + public void setDefaultPathProvider(IHDFFilePathProvider defaultPathProvider) { + this.defaultPathProvider = defaultPathProvider; + } } diff --git a/edexOsgi/com.raytheon.uf.edex.datadelivery.event/res/spring/event-datadelivery-ingest.xml b/edexOsgi/com.raytheon.uf.edex.datadelivery.event/res/spring/event-datadelivery-ingest.xml index 6b0bf48923..c6205fff12 100644 --- a/edexOsgi/com.raytheon.uf.edex.datadelivery.event/res/spring/event-datadelivery-ingest.xml +++ b/edexOsgi/com.raytheon.uf.edex.datadelivery.event/res/spring/event-datadelivery-ingest.xml @@ -20,13 +20,8 @@ class="com.raytheon.uf.edex.datadelivery.event.notification.NotificationPurge" depends-on="ddEventRegister" /> - - - - + errorHandlerRef="errorHandler"> diff --git a/edexOsgi/com.raytheon.uf.edex.datadelivery.harvester/res/spring/harvester-datadelivery.xml b/edexOsgi/com.raytheon.uf.edex.datadelivery.harvester/res/spring/harvester-datadelivery.xml index bfe8a42ca9..3781db8a84 100644 --- a/edexOsgi/com.raytheon.uf.edex.datadelivery.harvester/res/spring/harvester-datadelivery.xml +++ b/edexOsgi/com.raytheon.uf.edex.datadelivery.harvester/res/spring/harvester-datadelivery.xml @@ -10,12 +10,17 @@ + + + + @@ -35,19 +40,6 @@ - - - - - - - - - - @@ -67,6 +59,4 @@ - - \ No newline at end of file diff --git a/edexOsgi/com.raytheon.uf.edex.datadelivery.registry/res/spring/registry-datadelivery.xml b/edexOsgi/com.raytheon.uf.edex.datadelivery.registry/res/spring/registry-datadelivery.xml index ff513c5867..58ffd772e8 100644 --- a/edexOsgi/com.raytheon.uf.edex.datadelivery.registry/res/spring/registry-datadelivery.xml +++ b/edexOsgi/com.raytheon.uf.edex.datadelivery.registry/res/spring/registry-datadelivery.xml @@ -1,7 +1,6 @@ + xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd"> diff --git a/edexOsgi/com.raytheon.uf.edex.datadelivery.registry/res/spring/registry-federation-datadelivery.xml b/edexOsgi/com.raytheon.uf.edex.datadelivery.registry/res/spring/registry-federation-datadelivery.xml index 47f4fcb0e9..fd619e27e0 100644 --- a/edexOsgi/com.raytheon.uf.edex.datadelivery.registry/res/spring/registry-federation-datadelivery.xml +++ b/edexOsgi/com.raytheon.uf.edex.datadelivery.registry/res/spring/registry-federation-datadelivery.xml @@ -1,7 +1,6 @@ + xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd"> diff --git a/edexOsgi/com.raytheon.uf.edex.datadelivery.retrieval/res/spring/grid-metadata.xml b/edexOsgi/com.raytheon.uf.edex.datadelivery.retrieval/res/spring/grid-metadata.xml index f8fd0a929a..9107a68a81 100644 --- a/edexOsgi/com.raytheon.uf.edex.datadelivery.retrieval/res/spring/grid-metadata.xml +++ b/edexOsgi/com.raytheon.uf.edex.datadelivery.retrieval/res/spring/grid-metadata.xml @@ -1,7 +1,6 @@ + xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd"> diff --git a/edexOsgi/com.raytheon.uf.edex.dissemination/res/spring/dissemination-request.xml b/edexOsgi/com.raytheon.uf.edex.dissemination/res/spring/dissemination-request.xml index 83c351e7f2..dcdf235bb0 100644 --- a/edexOsgi/com.raytheon.uf.edex.dissemination/res/spring/dissemination-request.xml +++ b/edexOsgi/com.raytheon.uf.edex.dissemination/res/spring/dissemination-request.xml @@ -20,20 +20,6 @@ - - - - - - java.lang.Throwable - - - - - - - @@ -50,11 +36,21 @@ java.lang.Throwable + uri="log:oup?level=ERROR&showBody=true" />
+ + + + + + java.lang.Throwable + + + +
diff --git a/edexOsgi/com.raytheon.uf.edex.distribution/res/spring/distribution-spring.xml b/edexOsgi/com.raytheon.uf.edex.distribution/res/spring/distribution-spring.xml index 38cd142db1..e62a728e1b 100644 --- a/edexOsgi/com.raytheon.uf.edex.distribution/res/spring/distribution-spring.xml +++ b/edexOsgi/com.raytheon.uf.edex.distribution/res/spring/distribution-spring.xml @@ -10,8 +10,7 @@ + errorHandlerRef="errorHandler"> @@ -59,8 +58,4 @@
- - - 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 0ced6fe5ae..cf2c77856c 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.12.1174.qualifier +Bundle-Version: 1.14.0 Bundle-Vendor: Raytheon Bundle-RequiredExecutionEnvironment: JavaSE-1.6 Require-Bundle: org.apache.camel;bundle-version="1.0.0", @@ -19,7 +19,7 @@ Require-Bundle: org.apache.camel;bundle-version="1.0.0", com.raytheon.uf.common.comm;bundle-version="1.12.1174", com.raytheon.uf.common.json;bundle-version="1.0.0" Export-Package: com.raytheon.uf.edex.esb.camel, - com.raytheon.uf.edex.esb.camel.directvm, + com.raytheon.uf.edex.esb.camel.context, com.raytheon.uf.edex.esb.camel.jms Import-Package: com.raytheon.uf.common.event, com.raytheon.uf.common.message, diff --git a/edexOsgi/com.raytheon.uf.edex.esb.camel/src/com/raytheon/uf/edex/esb/camel/Executor.java b/edexOsgi/com.raytheon.uf.edex.esb.camel/src/com/raytheon/uf/edex/esb/camel/Executor.java index 7434b48ce8..2a11413746 100644 --- a/edexOsgi/com.raytheon.uf.edex.esb.camel/src/com/raytheon/uf/edex/esb/camel/Executor.java +++ b/edexOsgi/com.raytheon.uf.edex.esb.camel/src/com/raytheon/uf/edex/esb/camel/Executor.java @@ -31,7 +31,9 @@ import java.util.concurrent.CountDownLatch; import org.springframework.context.support.ClassPathXmlApplicationContext; +import com.raytheon.uf.common.time.util.TimeUtil; import com.raytheon.uf.common.util.PropertiesUtil; +import com.raytheon.uf.edex.core.EDEXUtil; import com.raytheon.uf.edex.core.modes.EDEXModesUtil; import com.raytheon.uf.edex.esb.camel.context.ContextManager; @@ -54,7 +56,7 @@ import com.raytheon.uf.edex.esb.camel.context.ContextManager; * Feb 14, 2013 1638 mschenke Removing activemq reference in stop * Apr 22, 2013 #1932 djohnson Use countdown latch for a shutdown hook. * Dec 04, 2013 2566 bgonzale refactored mode methods to a utility in edex.core. - * + * Mar 19, 2014 2726 rjpeter Added graceful shutdown. * * * @author chammack @@ -66,15 +68,36 @@ public class Executor { private static final CountDownLatch shutdownLatch = new CountDownLatch(1); public static void start() throws Exception { + final long t0 = System.currentTimeMillis(); Runtime.getRuntime().addShutdownHook(new Thread() { @Override public void run() { + ContextManager ctxMgr = ContextManager.getInstance(); + + long t1 = System.currentTimeMillis(); + System.out + .println("**************************************************"); + System.out + .println("* EDEX ESB is shutting down *"); + System.out + .println("**************************************************"); + ctxMgr.stopContexts(); + long t2 = System.currentTimeMillis(); + System.out + .println("**************************************************"); + System.out + .println("* EDEX ESB is shut down *"); + System.out.println("* Total time to shutdown: " + + TimeUtil.prettyDuration(t2 - t1)); + System.out.println("* EDEX ESB uptime: " + + TimeUtil.prettyDuration(t2 - t0)); + System.out + .println("**************************************************"); shutdownLatch.countDown(); } }); - long t0 = System.currentTimeMillis(); Thread.currentThread().setName("EDEXMain"); System.setProperty("System.status", "Starting"); @@ -113,7 +136,7 @@ public class Executor { String modeName = System.getProperty("edex.run.mode"); - if (modeName != null && modeName.length() > 0) { + if ((modeName != null) && (modeName.length() > 0)) { System.out.println("EDEX run configuration: " + modeName); } else { System.out @@ -123,8 +146,7 @@ public class Executor { + System.getProperty("aw.site.identifier")); List discoveredPlugins = EDEXModesUtil.extractSpringXmlFiles( - xmlFiles, - modeName); + xmlFiles, modeName); System.out.println(); System.out.println(" "); @@ -141,8 +163,10 @@ public class Executor { ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext( xmlFiles.toArray(new String[xmlFiles.size()])); + ContextManager ctxMgr = (ContextManager) context .getBean("contextManager"); + // start final routes ctxMgr.startContexts(); @@ -151,11 +175,12 @@ public class Executor { .println("**************************************************"); System.out .println("* EDEX ESB is now operational *"); - System.out.println("* Total startup time: " + ((t1 - t0) / 1000) - + " seconds"); + System.out.println("* Total startup time: " + + TimeUtil.prettyDuration(t1 - t0)); System.out .println("**************************************************"); System.setProperty("System.status", "Operational"); + EDEXUtil.notifyIsRunning(); shutdownLatch.await(); } diff --git a/edexOsgi/com.raytheon.uf.edex.esb.camel/src/com/raytheon/uf/edex/esb/camel/MessageProducer.java b/edexOsgi/com.raytheon.uf.edex.esb.camel/src/com/raytheon/uf/edex/esb/camel/MessageProducer.java index 3e590f25bf..b0a1e9f366 100644 --- a/edexOsgi/com.raytheon.uf.edex.esb.camel/src/com/raytheon/uf/edex/esb/camel/MessageProducer.java +++ b/edexOsgi/com.raytheon.uf.edex.esb.camel/src/com/raytheon/uf/edex/esb/camel/MessageProducer.java @@ -19,51 +19,106 @@ **/ package com.raytheon.uf.edex.esb.camel; -import java.util.ArrayList; import java.util.HashMap; +import java.util.LinkedList; import java.util.List; import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; +import javax.naming.ConfigurationException; + +import org.apache.camel.AsyncCallback; +import org.apache.camel.AsyncProcessor; import org.apache.camel.CamelContext; -import org.apache.camel.CamelExecutionException; +import org.apache.camel.Exchange; import org.apache.camel.ExchangePattern; +import org.apache.camel.Processor; import org.apache.camel.ProducerTemplate; import org.apache.camel.Route; -import org.springframework.beans.BeansException; -import org.springframework.context.ApplicationContext; -import org.springframework.context.ApplicationContextAware; +import org.apache.camel.model.ProcessorDefinition; +import org.apache.camel.spi.InterceptStrategy; import com.raytheon.uf.common.message.IMessage; +import com.raytheon.uf.common.status.IUFStatusHandler; +import com.raytheon.uf.common.status.UFStatus; +import com.raytheon.uf.common.util.Pair; import com.raytheon.uf.edex.core.EDEXUtil; import com.raytheon.uf.edex.core.EdexException; import com.raytheon.uf.edex.core.IMessageProducer; +import com.raytheon.uf.edex.esb.camel.context.ContextData; +import com.raytheon.uf.edex.esb.camel.context.ContextManager; /** - * Sends message to endpoints programmatically. + * Sends message to endpoints programmatically. Implements the camel + * {@link InterceptStrategy} to allow for tracking of camel dependencies where + * possible so that the ProducerTemplate is created from the correct context. * *
  * SOFTWARE HISTORY
  * Date         Ticket#    Engineer    Description
  * ------------ ---------- ----------- --------------------------
- * Nov 14, 2008            njensen     Initial creation
+ * Nov 14, 2008            njensen     Initial creation.
+ * Mar 27, 2014 2726       rjpeter     Modified for graceful shutdown changes.
  * 
* * @author njensen * @version 1.0 */ -public class MessageProducer implements ApplicationContextAware, - IMessageProducer { +public class MessageProducer implements IMessageProducer, InterceptStrategy { + private final IUFStatusHandler statusHandler = UFStatus + .getHandler(MessageProducer.class); - private static ApplicationContext springContext; + /* + * setup via an interceptor used for tracking what context the current + * thread is participating in for dependency management of runtime + * IMessageProducer message sends. + */ + private final ThreadLocal currentThreadContext = new ThreadLocal(); - private static List camelContextList; + private final ConcurrentMap contextProducerMap = new ConcurrentHashMap(); - private static Map endpointIdUriMap = new HashMap(); + /** + * List of messages waiting to be sent. + */ + private final List waitingMessages = new LinkedList(); - private static Map endpointContextMap = new HashMap(); + /** + * Internal variable for tracking if messages should be queued or not. + */ + private volatile boolean started = false; - private static Map contextProducerMap = new HashMap(); + /** + * Constructor that launches an internal thread that will send all async + * messages that queue up while camel starts up. + */ + public MessageProducer() { + Thread t = new Thread() { + @Override + public void run() { + EDEXUtil.waitForRunning(); + started = true; + sendPendingAsyncMessages(); + } + }; + t.setName("MessageProducer-pendingMessageSender"); + t.start(); + } + + /** + * Returns the ContextData + * + * @return + * @throws EdexException + */ + protected ContextData getContextData() throws EdexException { + try { + return ContextManager.getInstance().getContextData(); + } catch (ConfigurationException e) { + throw new EdexException("Unable to look up camel context data", e); + } + } /* * (non-Javadoc) @@ -72,21 +127,42 @@ public class MessageProducer implements ApplicationContextAware, * com.raytheon.uf.edex.esb.camel.IMessageProducer#sendAsync(java.lang.String * , java.lang.Object) */ + @Override public void sendAsync(String endpoint, Object message) throws EdexException { - CamelContext camelContext = getCamelContext(endpoint); - ProducerTemplate template = getProducerTemplate(camelContext); - String uri = endpointIdUriMap.get(endpoint); - Map headers = getHeaders(message); + if (!started && queueWaitingMessage(WaitingType.ID, endpoint, message)) { + return; + } + + String uri = getContextData().getEndpointUriForRouteId(endpoint); + sendAsyncUri(uri, message); + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.edex.core.IMessageProducer#sendAsyncUri(java.lang.String, + * java.lang.Object) + */ + @Override + public void sendAsyncUri(String uri, Object message) throws EdexException { + if (!started && queueWaitingMessage(WaitingType.URI, uri, message)) { + return; + } + try { + ProducerTemplate template = getProducerTemplateForUri(uri); + Map headers = getHeaders(message); + if (headers != null) { template.sendBodyAndHeaders(uri, ExchangePattern.InOnly, message, headers); } else { template.sendBody(uri, ExchangePattern.InOnly, message); } - } catch (CamelExecutionException e) { + } catch (Exception e) { throw new EdexException("Error sending asynchronous message: " - + message + " to endpoint: " + uri, e); + + message + " to uri: " + uri, e); } } @@ -97,114 +173,112 @@ public class MessageProducer implements ApplicationContextAware, * com.raytheon.uf.edex.esb.camel.IMessageProducer#sendSync(java.lang.String * , java.lang.Object) */ + @Override public Object sendSync(String endpoint, Object message) throws EdexException { - CamelContext camelContext = getCamelContext(endpoint); - ProducerTemplate template = getProducerTemplate(camelContext); - String uri = endpointIdUriMap.get(endpoint); - Map headers = getHeaders(message); + if (!started) { + throw new EdexException("Cannot send synchronous message to " + + endpoint + " before EDEX has started"); + } + + String uri = getContextData().getEndpointUriForRouteId(endpoint); + try { + ProducerTemplate template = getProducerTemplateForUri(uri); + Map headers = getHeaders(message); + if (headers != null) { return template.sendBodyAndHeaders(uri, ExchangePattern.OutIn, message, headers); } else { return template.sendBody(uri, ExchangePattern.OutIn, message); } - } catch (CamelExecutionException e) { + } catch (Exception e) { throw new EdexException("Error sending synchronous message: " + message + " to uri: " + uri, e); } } - private synchronized CamelContext getCamelContext(String endpointId) - throws EdexException { - CamelContext ctx = endpointContextMap.get(endpointId); + /** + * Queues up an async message for sending to an endpoint. + * + * @param type + * @param endpoint + * @param message + * @return + */ + private boolean queueWaitingMessage(WaitingType type, String endpoint, + Object message) { + synchronized (waitingMessages) { + // make sure container hasn't started while waiting + if (!started) { + WaitingMessage wm = new WaitingMessage(); + wm.type = type; + wm.dest = endpoint; + wm.msg = message; + waitingMessages.add(wm); + return true; + } + + return false; + } + } + + /** + * Returns the a producer template for the CamelContext this thread is + * currently a part of. If thread is not part of a context, will use context + * of the uri. If the uri is not registered in this jvm, will use the first + * context available. + * + * @return + */ + protected ProducerTemplate getProducerTemplateForUri(String uri) + throws ConfigurationException, EdexException { + CamelContext ctx = currentThreadContext.get(); + if (ctx == null) { - List list = getCamelContextList(); - boolean found = false; - for (CamelContext c : list) { - List routes = c.getRoutes(); - for (Route r : routes) { - if (r.getProperties() != null - && endpointId.equals(r.getProperties().get( - Route.ID_PROPERTY))) { - ctx = c; - endpointContextMap.put(endpointId, ctx); - endpointIdUriMap.put(endpointId, r.getEndpoint() - .getEndpointUri()); - found = true; - break; - } - } - if (found) { - break; + ContextData contextData = getContextData(); + Pair typeAndName = ContextData + .getEndpointTypeAndName(uri); + if (typeAndName != null) { + Route route = contextData.getRouteForEndpointName(typeAndName + .getSecond()); + if (route != null) { + ctx = route.getRouteContext().getCamelContext(); } } + if (ctx == null) { - throw new EdexException("Route id " + endpointId - + " not found. Check loaded spring configurations."); + // this jvm does not consume from this route, use first context + List contexts = contextData.getContexts(); + if (contexts.size() > 0) { + // should always be a context defined + ctx = contexts.iterator().next(); + } } } - return ctx; - } + if (ctx != null) { + ProducerTemplate tmp = contextProducerMap.get(ctx); + if (tmp == null) { + tmp = ctx.createProducerTemplate(); + ProducerTemplate prev = contextProducerMap + .putIfAbsent(ctx, tmp); + if ((prev != null) && (prev != tmp)) { + try { + tmp.stop(); + } catch (Exception e) { - private ProducerTemplate getProducerTemplate(CamelContext ctx) { - ProducerTemplate tmp = contextProducerMap.get(ctx); - if (tmp == null) { - tmp = ctx.createProducerTemplate(); - contextProducerMap.put(ctx, tmp); - } - - return tmp; - } - - private synchronized List getCamelContextList() { - if (springContext == null) { - springContext = EDEXUtil.getSpringContext(); - } - - if (springContext == null) { - - throw new IllegalStateException( - "Spring context has not been initialized on " - + MessageProducer.class.getName()); - } - - if (camelContextList == null) { - camelContextList = new ArrayList(); - String[] camelContexts = springContext - .getBeanNamesForType(CamelContext.class); - for (String name : camelContexts) { - CamelContext c = (CamelContext) springContext.getBean(name); - camelContextList.add(c); + } + tmp = prev; + } } + return tmp; } - return camelContextList; - } - @Override - public void setApplicationContext(ApplicationContext context) - throws BeansException { - springContext = context; - } - - @Override - public void sendAsyncUri(String uri, Object message) throws EdexException { - CamelContext ctx = getCamelContextList().get(0); - ProducerTemplate template = getProducerTemplate(ctx); - Map headers = getHeaders(message); - try { - if (headers != null) { - template.sendBodyAndHeaders(uri, ExchangePattern.InOnly, - message, headers); - } else { - template.sendBody(uri, ExchangePattern.InOnly, message); - } - } catch (CamelExecutionException e) { - throw new EdexException("Error sending asynchronous message: " + message - + " to uri: " + uri, e); - } + throw new ConfigurationException( + "Could not find a CamelContext for routing to uri [" + uri + + "]. Check loaded spring configurations."); } private Map getHeaders(Object message) { @@ -224,4 +298,90 @@ public class MessageProducer implements ApplicationContextAware, return headers; } + /** + * Sends any messages that were queued up while Camel started. + */ + protected void sendPendingAsyncMessages() { + synchronized (waitingMessages) { + for (WaitingMessage wm : waitingMessages) { + try { + switch (wm.type) { + case ID: + sendAsync(wm.dest, wm.msg); + break; + case URI: + sendAsyncUri(wm.dest, wm.msg); + break; + } + } catch (Exception e) { + statusHandler + .error("Error occurred sending startup delayed async message", + e); + } + } + } + } + + /** + * Setup for use with MessageProducer to track what context the current + * operating thread is using. + */ + @Override + public Processor wrapProcessorInInterceptors(final CamelContext context, + final ProcessorDefinition definition, final Processor target, + final Processor nextTarget) throws Exception { + return new AsyncProcessor() { + @Override + public void process(Exchange exchange) throws Exception { + /* + * track the thread this context is using for proper dependency + * management. + */ + MessageProducer.this.currentThreadContext.set(context); + target.process(exchange); + } + + @Override + public boolean process(Exchange exchange, AsyncCallback callback) { + /* + * track the thread this context is using for proper dependency + * management. + */ + MessageProducer.this.currentThreadContext.set(context); + + try { + target.process(exchange); + } catch (Throwable e) { + exchange.setException(e); + } + callback.done(true); + return true; + } + + @Override + public String toString() { + return "MessageProducer - ContainerWideInterceptor[" + target + + "]"; + } + + }; + } + + /** + * Enum for handling whether the waiting type was uri or msg. + */ + private enum WaitingType { + ID, URI + }; + + /** + * Inner class for handling messages sent before edex is up. + */ + private class WaitingMessage { + private WaitingType type; + + private String dest; + + private Object msg; + } } diff --git a/edexOsgi/com.raytheon.uf.edex.esb.camel/src/com/raytheon/uf/edex/esb/camel/StringToFile.java b/edexOsgi/com.raytheon.uf.edex.esb.camel/src/com/raytheon/uf/edex/esb/camel/StringToFile.java index d20bf6f7e8..1aeaf3a1a4 100644 --- a/edexOsgi/com.raytheon.uf.edex.esb.camel/src/com/raytheon/uf/edex/esb/camel/StringToFile.java +++ b/edexOsgi/com.raytheon.uf.edex.esb.camel/src/com/raytheon/uf/edex/esb/camel/StringToFile.java @@ -20,12 +20,13 @@ package com.raytheon.uf.edex.esb.camel; import java.io.File; -import java.io.FileNotFoundException; import org.apache.camel.Exchange; import org.apache.camel.Processor; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; + +import com.raytheon.uf.common.status.IUFStatusHandler; +import com.raytheon.uf.common.status.UFStatus; +import com.raytheon.uf.common.status.UFStatus.Priority; /** * Performs a transform from Strings to Files @@ -38,9 +39,9 @@ import org.apache.commons.logging.LogFactory; * SOFTWARE HISTORY * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- - * Dec 1, 2008 chammack Initial creation - * 15Jul2010 6624 garmendariz Log error and interrupt if file missing - * + * Dec 1, 2008 chammack Initial creation. + * 15Jul2010 6624 garmendariz Log error and interrupt if file missing. + * Mar 19, 2014 2726 rjpeter Added debug logging of file being processed. * * * @author chammack @@ -49,7 +50,8 @@ import org.apache.commons.logging.LogFactory; public class StringToFile implements Processor { - protected transient Log logger = LogFactory.getLog(getClass()); + protected final IUFStatusHandler statusHandler = UFStatus + .getHandler(StringToFile.class); /* * (non-Javadoc) @@ -69,12 +71,15 @@ public class StringToFile implements Processor { // if file does not exist, set fault to interrupt processing if (!file.exists()) { - logger.error("File does not exist : " + bodyString); + statusHandler.error("File does not exist : " + bodyString); arg0.getOut().setFault(true); } else { arg0.getIn().setBody(file); arg0.getIn().setHeader("ingestFileName", file.toString()); arg0.getIn().setHeader("dequeueTime", System.currentTimeMillis()); + if (statusHandler.isPriorityEnabled(Priority.DEBUG)) { + statusHandler.debug("Processing file: " + file.toString()); + } } } } diff --git a/edexOsgi/com.raytheon.uf.edex.esb.camel/src/com/raytheon/uf/edex/esb/camel/context/ClusteredContextManager.java b/edexOsgi/com.raytheon.uf.edex.esb.camel/src/com/raytheon/uf/edex/esb/camel/context/ClusteredContextManager.java deleted file mode 100644 index 910a3d06a4..0000000000 --- a/edexOsgi/com.raytheon.uf.edex.esb.camel/src/com/raytheon/uf/edex/esb/camel/context/ClusteredContextManager.java +++ /dev/null @@ -1,190 +0,0 @@ -/** - * 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.esb.camel.context; - -import java.net.InetAddress; -import java.net.NetworkInterface; -import java.net.SocketException; -import java.util.ArrayList; -import java.util.Enumeration; -import java.util.List; - -import org.apache.camel.CamelContext; -import org.apache.camel.Route; -import org.apache.camel.ServiceStatus; - -import com.raytheon.uf.common.status.IUFStatusHandler; -import com.raytheon.uf.common.status.UFStatus; -import com.raytheon.uf.common.status.UFStatus.Priority; -import com.raytheon.uf.edex.database.cluster.ClusterLockUtils; -import com.raytheon.uf.edex.database.cluster.ClusterTask; - -/** - * Dynamically starts/stops a context and its associated routes so that only one - * context in the cluster is running. This should mainly be used for reading - * from topics so that only box is processing the topic data in the cluster for - * singleton type events. - * - *
- * SOFTWARE HISTORY
- * 
- * Date         Ticket#    Engineer    Description
- * ------------ ---------- ----------- --------------------------
- * Nov 10, 2010 5050       rjpeter     Initial creation
- * Jul 16, 2012 DR 15073   D. Friedman Stop consumers instead of whole context
- * May 14, 2013 1989       njensen     Camel 2.11 compatibility
- * Aug 26, 2013 DR 2272    bkowal      Append an optional suffix to the cluster task details
- * 
- * - * @author rjpeter - * @version 1.0 - */ -public class ClusteredContextManager { - private static final transient IUFStatusHandler statusHandler = UFStatus - .getHandler(ClusteredContextManager.class); - - private static final String taskName = "ClusteredContext"; - - private String myName; - - private List clusteredContextList = new ArrayList(); - - private int timeOutMillis; - - private static ClusteredContextManager instance = new ClusteredContextManager(); - - public static ClusteredContextManager getInstance() { - return instance; - } - - private ClusteredContextManager() { - myName = getHostName() + ":" + System.getProperty("edex.run.mode"); - } - - private static String getHostName() { - String hostname = System.getenv("HOSTNAME"); - if (hostname == null) { - hostname = System.getenv("COMPUTERNAME"); - } - if (hostname == null) { - hostname = System.getenv("HOST"); - } - if (hostname == null) { - try { - Enumeration nis = NetworkInterface - .getNetworkInterfaces(); - while (nis.hasMoreElements()) { - NetworkInterface ni = nis.nextElement(); - ni.isVirtual(); - ni.isUp(); - Enumeration addrs = ni.getInetAddresses(); - while (addrs.hasMoreElements()) { - InetAddress addr = addrs.nextElement(); - if (addr.isLinkLocalAddress() == false - && addr.isSiteLocalAddress() == false - && addr.isLoopbackAddress() == false) { - hostname = addr.getHostName(); - } - } - } - } catch (SocketException e) { - statusHandler.handle(Priority.ERROR, - "Failed to determine hostname", e); - } - } - return hostname; - } - - public void checkClusteredContexts() { - String suffix = ClusterLockUtils.CLUSTER_SUFFIX; - for (CamelContext camelContext : clusteredContextList) { - String contextName = camelContext.getName() + suffix; - ClusterTask lock = ClusterLockUtils.lock(taskName, contextName, - myName, timeOutMillis, false); - boolean activateRoute = false; - - switch (lock.getLockState()) { - case ALREADY_RUNNING: - // check if we already have lock - activateRoute = lock.getExtraInfo().equals(myName); - break; - case SUCCESSFUL: - activateRoute = true; - break; - default: - } - - try { - if (activateRoute) { - ClusterLockUtils.updateLockTime(taskName, contextName, - System.currentTimeMillis()); - - for (Route route : camelContext.getRoutes()) { - String routeId = route.getId(); - ServiceStatus status = camelContext - .getRouteStatus(routeId); - if (status == ServiceStatus.Stopped - || status == ServiceStatus.Stopping) { - camelContext.startRoute(routeId); - } else if (status == ServiceStatus.Suspended - || status == ServiceStatus.Suspending) { - camelContext.resumeRoute(routeId); - } - } - } else { - for (Route route : camelContext.getRoutes()) { - String routeId = route.getId(); - ServiceStatus status = camelContext - .getRouteStatus(routeId); - if (status == ServiceStatus.Started - || status == ServiceStatus.Starting) { - // CamelContext API says to use suspend, not stop - camelContext.suspendRoute(routeId); - } - } - } - } catch (Exception e) { - StringBuilder msg = new StringBuilder(); - msg.append("Failed to "); - if (activateRoute) { - msg.append("start "); - } else { - msg.append("suspend "); - } - msg.append("context "); - msg.append(camelContext.getName()); - statusHandler.handle(Priority.ERROR, msg.toString(), e); - } - } - } - - public ClusteredContextManager register(CamelContext context) { - clusteredContextList.add(context); - return this; - } - - public int getTimeOutMillis() { - return timeOutMillis; - } - - public void setTimeOutMillis(int timeOutMillis) { - this.timeOutMillis = timeOutMillis; - } -} diff --git a/edexOsgi/com.raytheon.uf.edex.esb.camel/src/com/raytheon/uf/edex/esb/camel/context/ClusteredContextStateManager.java b/edexOsgi/com.raytheon.uf.edex.esb.camel/src/com/raytheon/uf/edex/esb/camel/context/ClusteredContextStateManager.java new file mode 100644 index 0000000000..a673e5754c --- /dev/null +++ b/edexOsgi/com.raytheon.uf.edex.esb.camel/src/com/raytheon/uf/edex/esb/camel/context/ClusteredContextStateManager.java @@ -0,0 +1,144 @@ +/** + * 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.esb.camel.context; + +import java.util.concurrent.ExecutorService; + +import org.apache.camel.CamelContext; + +import com.raytheon.uf.common.util.SystemUtil; +import com.raytheon.uf.edex.database.cluster.ClusterLockUtils; +import com.raytheon.uf.edex.database.cluster.ClusterTask; + +/** + * Implementation of {@link IContextStateManager} that handles clustered + * contexts. Extends {@code DependencyContextStateManager} to allow for + * clustered contexts to work with dependencies also. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Apr 10, 2014 2726       rjpeter     Initial creation
+ * 
+ * 
+ * + * @author rjpeter + * @version 1.0 + */ +public class ClusteredContextStateManager extends DependencyContextStateManager { + + /** + * Name field for cluster task. + */ + private static final String taskName = "ClusteredContext"; + + /** + * Field for extra-info to designate this host. + */ + private final String myName; + + /** + * Constructor that takes an {@code ExecutorService}. The + * {@code ExecutorService} is used for starting/stopping dependent contexts. + * + * @param service + */ + public ClusteredContextStateManager(ExecutorService service) { + super(service); + myName = SystemUtil.getHostName() + ":" + + System.getProperty("edex.run.mode"); + } + + /** + * Get the {@code ClusterLock} details field. + * + * @param context + * @return + */ + protected static String getLockDetails(CamelContext context) { + return context.getName() + ClusterLockUtils.CLUSTER_SUFFIX; + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.edex.esb.camel.context.DependencyContextStateManager# + * isContextStartable(org.apache.camel.CamelContext) + */ + @Override + public boolean isContextStartable(CamelContext context) throws Exception { + boolean canStartContext = super.isContextStartable(context); + + /* + * Check cluster lock if we can start the context or if context is + * already started in case we need to update the cluster lock. + */ + if (canStartContext || context.getStatus().isStarted()) { + ClusterTask lock = ClusterLockUtils.lock(taskName, + getLockDetails(context), myName, ContextManager + .getInstance().getTimeOutMillis(), false); + + switch (lock.getLockState()) { + case ALREADY_RUNNING: + // check if we already have lock + canStartContext = lock.getExtraInfo().equals(myName); + if (canStartContext) { + // update the lock time + ClusterLockUtils + .updateLockTime(taskName, getLockDetails(context), + System.currentTimeMillis()); + } + break; + case SUCCESSFUL: + canStartContext = true; + break; + + default: + canStartContext = false; + } + } + + return canStartContext; + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.edex.esb.camel.context.DependencyContextStateManager# + * stopContext(org.apache.camel.CamelContext) + */ + @Override + public boolean stopContext(CamelContext context) throws Exception { + // on stop, unlock the cluster lock if we own it + String contextName = context.getName() + + ClusterLockUtils.CLUSTER_SUFFIX; + ClusterTask lock = ClusterLockUtils.lookupLock(taskName, contextName); + if (lock.getExtraInfo().equals(myName) && lock.isRunning()) { + ClusterLockUtils.unlock(taskName, contextName); + } + + return super.stopContext(context); + } +} diff --git a/edexOsgi/com.raytheon.uf.edex.esb.camel/src/com/raytheon/uf/edex/esb/camel/context/ContextData.java b/edexOsgi/com.raytheon.uf.edex.esb.camel/src/com/raytheon/uf/edex/esb/camel/context/ContextData.java new file mode 100644 index 0000000000..bf6b01c8ac --- /dev/null +++ b/edexOsgi/com.raytheon.uf.edex.esb.camel/src/com/raytheon/uf/edex/esb/camel/context/ContextData.java @@ -0,0 +1,222 @@ +/** + * 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.esb.camel.context; + +import java.util.Collections; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import javax.naming.ConfigurationException; + +import org.apache.camel.CamelContext; +import org.apache.camel.Route; + +import com.raytheon.uf.common.util.Pair; +import com.raytheon.uf.edex.core.EdexException; + +/** + * Contains all known contexts and parsed data about the contexts. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Apr 10, 2014 2726       rjpeter     Initial creation
+ * 
+ * 
+ * + * @author rjpeter + * @version 1.0 + */ +public class ContextData { + private final List contexts; + + private final Map consumerRouteMapping; + + private final Map routeIdUriMapping; + + /** + * Pulls the direct-vm:name, vm:name, queue:name, topic:name section from + * the endpoint URI. + */ + private static final Pattern endpointUriParsePattern = Pattern + .compile("([^:]+)://([^?]+)"); + + /** + * Parses passed contexts for route and endpoint data about all contexts. + * + * @param contexts + * @throws ConfigurationException + */ + public ContextData(List contexts) + throws ConfigurationException { + this.contexts = Collections.unmodifiableList(contexts); + this.consumerRouteMapping = Collections + .unmodifiableMap(generateRouteMappings(this.contexts)); + Map idUriMapping = new HashMap( + consumerRouteMapping.size(), 1); + for (Route route : consumerRouteMapping.values()) { + idUriMapping.put(route.getId(), route.getEndpoint() + .getEndpointUri()); + } + + this.routeIdUriMapping = Collections.unmodifiableMap(idUriMapping); + } + + /** + * Populates an endpointName to {@code Route} mapping for the passed + * {@code CamelContext}s. + * + * @return + * @throws ConfigurationException + */ + protected static Map generateRouteMappings( + List contexts) throws ConfigurationException { + Map routeMapping = new HashMap( + contexts.size() * 2, 1); + + // populate the consumer definitions + for (CamelContext context : contexts) { + List routes = context.getRoutes(); + if ((routes != null) && (routes.size() > 0)) { + for (Route route : routes) { + String uri = route.getEndpoint().getEndpointUri(); + Pair typeAndName = getEndpointTypeAndName(uri); + if (typeAndName != null) { + String endpointName = typeAndName.getSecond(); + + Route prev = routeMapping.put(endpointName, route); + if (prev != null) { + throw new ConfigurationException( + "Two contexts listen to the same endpoint name [" + + endpointName + + "]. ContextManager cannot handle this situation. Double check configuration. Conflicting contexts [" + + prev.getRouteContext() + .getCamelContext() + .getName() + "] and [" + + context.getName() + "]"); + } + } + } + } + } + return routeMapping; + } + + /** + * Returns the known contexts. + * + * @return + */ + public List getContexts() { + return contexts; + } + + /** + * Parses URI for component type and endpoint name. + * + * @param uri + * @return + */ + public static Pair getEndpointTypeAndName(String uri) { + Pair rval = null; + Matcher m = endpointUriParsePattern.matcher(uri); + + if (m.find()) { + String endpointType = m.group(1); + String endpointName = m.group(2); + rval = new Pair(endpointType, endpointName); + } + + return rval; + } + + /** + * Scans the camel context and associated routes. Groups the routes by + * consumer type. + * + * @return + */ + public Map> getContextRoutesByEndpointType() + throws ConfigurationException { + Map> routesByType = new HashMap>(); + for (CamelContext context : contexts) { + List routes = context.getRoutes(); + if ((routes != null) && (routes.size() > 0)) { + for (Route route : routes) { + String uri = route.getEndpoint().getEndpointUri(); + Pair typeAndName = getEndpointTypeAndName(uri); + String type = typeAndName.getFirst(); + List routesForType = routesByType.get(type); + if (routesForType == null) { + routesForType = new LinkedList(); + routesByType.put(type, routesForType); + } + routesForType.add(route); + } + } + } + + return routesByType; + } + + /** + * Returns the uri for the consumer endpoint of the route with the specified + * routeId. + * + * @param routeId + * @return + * @throws EdexException + */ + public String getEndpointUriForRouteId(String routeId) throws EdexException { + String uri = routeIdUriMapping.get(routeId); + if (uri == null) { + throw new EdexException("Route id " + routeId + + " not found. Check loaded spring configurations."); + } + + return uri; + } + + /** + * Returns the route for the endpoint with the passed name as returned from + * getEndpointTypeAndName(). + * + * @param endpointName + * @return + * @throws EdexException + */ + public Route getRouteForEndpointName(String endpointName) + throws EdexException { + Route route = consumerRouteMapping.get(endpointName); + if (route == null) { + throw new EdexException("Endpoint " + endpointName + + " not found. Check loaded spring configurations."); + } + + return route; + } +} diff --git a/edexOsgi/com.raytheon.uf.edex.esb.camel/src/com/raytheon/uf/edex/esb/camel/context/ContextDependencyMapping.java b/edexOsgi/com.raytheon.uf.edex.esb.camel/src/com/raytheon/uf/edex/esb/camel/context/ContextDependencyMapping.java new file mode 100644 index 0000000000..b556459528 --- /dev/null +++ b/edexOsgi/com.raytheon.uf.edex.esb.camel/src/com/raytheon/uf/edex/esb/camel/context/ContextDependencyMapping.java @@ -0,0 +1,268 @@ +/** + * 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.esb.camel.context; + +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import javax.naming.ConfigurationException; + +import org.apache.camel.CamelContext; +import org.apache.camel.Endpoint; +import org.apache.camel.Route; + +import com.raytheon.uf.common.status.IUFStatusHandler; +import com.raytheon.uf.common.status.UFStatus; +import com.raytheon.uf.common.util.Pair; + +/** + * Contains context dependency mappings. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Mar 26, 2014 2726       rjpeter     Initial creation
+ * 
+ * 
+ * + * @author rjpeter + * @version 1.0 + */ +public class ContextDependencyMapping { + /** + * Endpoint types that should be tracked for dependency mapping + */ + protected static final Set DEPENDENCY_ENDPOINT_TYPES; + + static { + /* + * Endpoint types that are used for inner context routing. If we add + * other inner jvm routing types, they should be added here. + */ + Set types = new HashSet(8); + types.add("vm"); + types.add("direct-vm"); + types.add("seda"); + types.add("jmx"); + types.add("guava-eventbus"); + DEPENDENCY_ENDPOINT_TYPES = Collections.unmodifiableSet(types); + } + + /** + * The dependency mappings. + */ + protected final Map dependencyMapping; + + /** + * Populates the dependency mappings for all camel contexts. + * {@code suppressExceptions} can be used to differentiate between + * startup/shutdown conditions to allow the map to be populated regardless + * of detected issues. + * + * @param contextData + * @param suppressExceptions + * @throws ConfigurationException + */ + public ContextDependencyMapping(ContextData contextData, + boolean suppressExceptions) throws ConfigurationException { + dependencyMapping = Collections + .unmodifiableMap(populateDependencyMapping(contextData, + suppressExceptions)); + } + + /** + * Returns a {@code IUFStatusHandler}. Not cached as rarely used. + * + * @return + */ + private static IUFStatusHandler getHandler() { + return UFStatus.getHandler(ContextDependencyMapping.class); + } + + /** + * Dependency mappings per context. The dependency mapping is only for + * internal vm types that have a direct dependency. Indirect dependency via + * a JMS queue for example is not returned/enforced. + * + * @param contextData + * @param suppressExceptions + * Done in a shutdown scenario to get the dependencyMapping as + * close as possible. + */ + protected static Map populateDependencyMapping( + ContextData contextData, boolean suppressExceptions) + throws ConfigurationException { + List contexts = contextData.getContexts(); + Map dependencyMapping = new LinkedHashMap( + contexts.size()); + + // set up dependency nodes for internal types + Map consumesFrom = new HashMap(); + Map> producesTo = new HashMap>(); + Set consumers = new HashSet(); + + // scan for consuming and producing internal endpoints + for (CamelContext context : contexts) { + dependencyMapping.put(context, new DependencyNode(context)); + consumers.clear(); + List routes = context.getRoutes(); + if ((routes != null) && (routes.size() > 0)) { + for (Route route : routes) { + String uri = route.getEndpoint().getEndpointUri(); + Pair typeAndName = ContextData + .getEndpointTypeAndName(uri); + if ((typeAndName != null) + && DEPENDENCY_ENDPOINT_TYPES.contains(typeAndName + .getFirst())) { + String endpointName = typeAndName.getSecond(); + consumers.add(endpointName); + + /* + * Internal types don't support a fanout type policy + * where multiple routes can listen to the same + * endpoint. + */ + CamelContext prev = consumesFrom.put(endpointName, + context); + if (prev != null) { + String msg = "Two contexts listen to the same internal endpoint [" + + endpointName + + "]. ContextManager cannot handle this situation. Double check configuration. Conflicting contexts [" + + prev.getName() + + "] and [" + + context.getName() + "]"; + if (suppressExceptions) { + getHandler().error(msg); + } else { + throw new ConfigurationException(msg); + } + } + } + } + } + + Collection endpoints = context.getEndpoints(); + if ((endpoints != null) && (endpoints.size() > 0)) { + for (Endpoint ep : endpoints) { + String uri = ep.getEndpointUri(); + Pair typeAndName = ContextData + .getEndpointTypeAndName(uri); + if ((typeAndName != null) + && DEPENDENCY_ENDPOINT_TYPES.contains(typeAndName + .getFirst())) { + String endpointName = typeAndName.getSecond(); + if (!consumers.contains(endpointName)) { + List producerCtxs = producesTo + .get(endpointName); + if (producerCtxs == null) { + producerCtxs = new LinkedList(); + producesTo.put(endpointName, producerCtxs); + } + producerCtxs.add(context); + } + } + } + } + } + + // setup dependencies for internal routes + for (Map.Entry> producersEntry : producesTo + .entrySet()) { + String endpoint = producersEntry.getKey(); + CamelContext consumer = consumesFrom.get(endpoint); + List producers = producersEntry.getValue(); + + if (consumer == null) { + StringBuilder msg = new StringBuilder(200); + msg.append("Internal Routing Endpoint [") + .append(endpoint) + .append("] has no defined consumers. This is endpoint is used in contexts ["); + Iterator producerIter = producers.iterator(); + + while (producerIter.hasNext()) { + CamelContext producer = producerIter.next(); + msg.append(producer.getName()); + + if (producerIter.hasNext()) { + msg.append(", "); + } + } + + msg.append("]"); + if (suppressExceptions) { + getHandler().error(msg.toString()); + } else { + throw new ConfigurationException(msg.toString()); + } + } else { + DependencyNode consumerNode = dependencyMapping.get(consumer); + for (CamelContext producer : producers) { + DependencyNode producerNode = dependencyMapping + .get(producer); + consumerNode.addDependentNode(producerNode); + } + } + } + return dependencyMapping; + } + + /** + * Get the contexts that depend upon the passed context to work. If the + * passed context is unknown null will be returned. + * + * @param context + * @return + */ + public Set getDependentContexts(CamelContext context) { + DependencyNode dNode = dependencyMapping.get(context); + if (dNode == null) { + return null; + } + + return dNode.getDependentContexts(); + } + + /** + * Get the contexts that the passed context requires to be running to work. + * If the passed context is unknown null will be returned. + * + * @param context + * @return + */ + public Set getRequiredContexts(CamelContext context) { + DependencyNode dNode = dependencyMapping.get(context); + if (dNode == null) { + return null; + } + + return dNode.getRequiredContexts(); + } +} 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 4a8e4dd72b..325d76314e 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 @@ -1,96 +1,587 @@ /** * 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.esb.camel.context; import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedList; import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.concurrent.atomic.AtomicBoolean; + +import javax.naming.ConfigurationException; import org.apache.camel.CamelContext; +import org.apache.camel.Route; +import org.apache.camel.impl.DefaultCamelContext; +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.config.BeanFactoryPostProcessor; +import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; 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.common.util.Pair; +import com.raytheon.uf.edex.core.IContextStateProcessor; /** - * Dynamically starts/stops a context and its associated routes so that only one - * context in the cluster is running. This should mainly be used for reading - * from topics so that only box is processing the topic data in the cluster for - * singleton type events. + * Tracks all contexts and is used to auto determine context dependencies and + * start/stop them in the right order. Dynamically starts/stops a clustered + * context and its associated routes so that only one context in the cluster is + * running. This should mainly be used for reading from topics so that only box + * is processing the topic data in the cluster for singleton type events. * *
  * SOFTWARE HISTORY
  * 
  * Date         Ticket#    Engineer    Description
  * ------------ ---------- ----------- --------------------------
- * Nov 10, 2010 5050       rjpeter     Initial creation
- * May 13, 2013 1989       njensen     Camel 2.11 compatibility
+ * Nov 10, 2010 5050       rjpeter     Initial creation.
+ * May 13, 2013 1989       njensen     Camel 2.11 compatibility.
+ * Mar 11, 2014 2726       rjpeter     Implemented graceful shutdown.
  * 
* * @author rjpeter * @version 1.0 */ -public class ContextManager { +public class ContextManager implements ApplicationContextAware, + BeanFactoryPostProcessor { private static final transient IUFStatusHandler statusHandler = UFStatus .getHandler(ContextManager.class); - private List contextList = new ArrayList(); - private static ContextManager instance = new ContextManager(); + /** + * Service used for start up and shut down threading. + */ + private final ExecutorService service = Executors.newCachedThreadPool(); + + private final Set clusteredContexts = new HashSet(); + + /** + * State Manager for all contexts that are not clustered. + */ + private final IContextStateManager defaultStateManager = new DependencyContextStateManager( + service); + + /** + * State Manager used for all clustered contexts. + */ + private final IContextStateManager clusteredStateManager = new ClusteredContextStateManager( + service); + + /** + * Spring context. Set by the spring container after bean construction. + */ + private ApplicationContext springCtx = null; + + /** + * Endpoint types that are internal only. Mainly used at shutdown time to + * designate routes that shouldn't be shutdown immediately. + */ + private final Set internalEndpointTypes = new HashSet(); + + /** + * Map of context processors that have been registered for a given context. + * Used to allow contexts to do custom worn on startup/shutdown. + */ + private final Map contextProcessors = new HashMap(); + + /** + * Cluster lock timeout for clustered contexts. + */ + private int timeOutMillis; + + /** + * Parsed context data for all contexts known in the spring container. + */ + private volatile ContextData contextData; + + /** + * Flag to control shutting down the jvm. This handles shutdown being called + * during startup to short circuit startup. + */ + private final AtomicBoolean shuttingDown = new AtomicBoolean(false); + + /** + * Dependency mappings for all camel contexts in the spring container. This + * should only be changed in a sync block. Otherwise mark as volatile. + */ + private ContextDependencyMapping dependencyMapping = null; + + /** + * Last time dependency mapping was generated. Used to periodically + * regenerate the dependency mappings. + */ + private final long lastDependencyTime = 0; + public static ContextManager getInstance() { return instance; } + /** + * Private constructor. Sets up internal types for prioritized stopping of + * routes on shutdown. + */ private ContextManager() { + internalEndpointTypes + .addAll(ContextDependencyMapping.DEPENDENCY_ENDPOINT_TYPES); + internalEndpointTypes.add("timer"); + internalEndpointTypes.add("quartz"); + internalEndpointTypes.add("clusteredquartz"); } + /** + * Gets the context data. + * + * @return + * @throws ConfigurationException + */ + public ContextData getContextData() throws ConfigurationException { + if (contextData == null) { + synchronized (this) { + if (contextData == null) { + contextData = new ContextData(new ArrayList( + springCtx.getBeansOfType(CamelContext.class) + .values())); + } + } + } + + return contextData; + } + + /** + * Get the {@link IContextStateManager} for the passed {@code CamelContext}. + * + * @param context + * @return + */ + protected IContextStateManager getStateManager(CamelContext context) { + if (clusteredContexts.contains(context)) { + return clusteredStateManager; + } + + return defaultStateManager; + } + + /** + * Get the {@link IContextStateProcessor} for the passed + * {@code CamelContext}. + * + * @param context + * @return + */ + public IContextStateProcessor getStateProcessor(CamelContext context) { + return contextProcessors.get(context); + } + + /** + * Get the {@link ContextDependencyMapping} for all contexts. + * + * @param suppressExceptions + * @return + * @throws ConfigurationException + */ + public ContextDependencyMapping getDependencyMapping( + boolean suppressExceptions) throws ConfigurationException { + /* + * This is not permanently cashed and regenerated periodically since + * routing via code can change at runtime. + */ + synchronized (this) { + long millis = System.currentTimeMillis(); + if ((dependencyMapping == null) + || (millis > (lastDependencyTime + TimeUtil.MILLIS_PER_MINUTE))) { + dependencyMapping = new ContextDependencyMapping( + getContextData(), suppressExceptions); + } + } + + return dependencyMapping; + + } + + /** + * Starts all routes for all contexts. If a route fails to start the entire + * jvm will be shutdown. + */ public void startContexts() { - statusHandler.info("Context Manager starting routes"); - for (CamelContext camelContext : contextList) { + statusHandler.info("Context Manager starting contexts"); + + try { + ContextData cxtData = getContextData(); + List>> callbacks = new LinkedList>>(); + + for (final CamelContext context : cxtData.getContexts()) { + final IContextStateManager stateManager = getStateManager(context); + if (stateManager.isContextStartable(context)) { + /* + * Have the ExecutorService start the context to allow for + * quicker startup. + */ + callbacks + .add(service + .submit(new Callable>() { + @Override + public Pair call() + throws Exception { + boolean rval = false; + try { + rval = stateManager + .startContext(context); + + if (!rval) { + statusHandler.error("Context [" + + context.getName() + + "] failed to start, shutting down"); + System.exit(1); + } + } catch (Throwable e) { + statusHandler.fatal( + "Error occurred starting context: " + + context + .getName(), + e); + System.exit(1); + } + + return new Pair( + context, rval); + } + })); + } + } + + /* + * Double check call backs that everything started successfully. If + * some did not start successfully, force shutdown. + */ + for (Future> callback : callbacks) { + Pair val = callback.get(); + if (!val.getSecond().booleanValue()) { + statusHandler.error("Context [" + val.getFirst().getName() + + "] failed to start, shutting down"); + System.exit(1); + } + } + + } catch (Throwable e) { + statusHandler.fatal( + "Error occurred starting contexts, shutting down", e); + System.exit(1); + } + } + + /** + * Register a clustered context that is meant to run as a singleton in the + * cluster. + * + * @param context + * @return + */ + public ContextManager registerClusteredContext(final CamelContext context) { + clusteredContexts.add(context); + return this; + } + + /** + * Register a context state processor to be called on start/stop of the + * context. + * + * @param context + * @param processor + * @return + */ + public ContextManager registerContextStateProcessor( + final CamelContext context, final IContextStateProcessor processor) { + contextProcessors.put(context, processor); + return this; + } + + /** + * Stops all contexts. Note this method can only be called once for the life + * of the jvm and will gracefully shut down all of camel. + */ + public void stopContexts() { + /* + * flag to ensure no one else runs shutdown also stops + * checkClusteredContext from starting contexts once shutdown has been + * initiated + */ + if (shuttingDown.compareAndSet(false, true)) { + if (springCtx == null) { + statusHandler + .info("Spring Context not set. Start up never completed, cannot orderly shutdown"); + } + + statusHandler.info("Context Manager stopping routes"); + try { /* - * In camel 2.11, all contexts are "started" automatically but - * the isAutoStartup() flag determines if the routes are - * automatically started. The code in DefaultCamelContext is - * safe to call start() on a second time to get the routes - * started. - * - * For more information, see: - * http://camel.465427.n5.nabble.com/Camel - * -context-autostartup-td5721638.html - * - * https://issues.apache.org/jira/browse/CAMEL-5759 + * begin immediate shutdown of routes that are not an internal + * type */ - if (!camelContext.isAutoStartup()) { - camelContext.start(); + 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(); + } } - } catch (Exception e) { - statusHandler.handle(Priority.ERROR, - "Failed to start routes for " + camelContext.getName(), - e); + + 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) { + statusHandler.error("Context [" + failure.getName() + + "] had a failure trying to stop"); + } + } catch (Throwable e) { + statusHandler.fatal("Error occurred during shutdown", e); } } } - public ContextManager register(CamelContext context) { - contextList.add(context); - return this; + /** + * Waits for all callbacks to finish printing a periodic message with number + * of remaining callbacks. Returns a list of contexts that had a failure + * status. + * + * @param callbacks + * @param message + * @param sleepInterval + * @return + */ + private static List waitForCallbacks( + List>> callbacks, + String message, long sleepInterval) { + statusHandler.info(message + callbacks.size() + " remaining"); + List failures = new LinkedList(); + + while (!callbacks.isEmpty()) { + boolean foundOne = false; + + Iterator>> callbackIter = callbacks + .iterator(); + while (callbackIter.hasNext()) { + Future> callback = callbackIter + .next(); + if (callback.isDone()) { + foundOne = true; + callbackIter.remove(); + try { + Pair val = callback.get(); + if (!val.getSecond().booleanValue()) { + failures.add(val.getFirst()); + } + } catch (Exception e) { + statusHandler.error("Failure in callback task", e); + } + } + } + + if (!foundOne) { + statusHandler.info(message + callbacks.size() + " remaining"); + try { + Thread.sleep(sleepInterval); + } catch (Exception e) { + // ignore + } + } + } + + return failures; + } + + /** + * Checks the clustered contexts. If context is not running in the cluster + * the context will be started. + */ + public void checkClusteredContexts() { + if (!shuttingDown.get()) { + for (CamelContext camelContext : clusteredContexts) { + boolean activateRoute = true; + try { + IContextStateManager stateManager = getStateManager(camelContext); + + if (stateManager.isContextStartable(camelContext)) { + stateManager.startContext(camelContext); + } else if (stateManager.isContextStoppable(camelContext)) { + activateRoute = false; + stateManager.stopContext(camelContext); + } + } catch (Exception e) { + StringBuilder msg = new StringBuilder(); + msg.append("Failed to "); + if (activateRoute) { + msg.append("start "); + } else { + msg.append("stop "); + } + msg.append("context "); + msg.append(camelContext.getName()); + statusHandler.handle(Priority.ERROR, msg.toString(), e); + } + } + } + } + + @Override + public void setApplicationContext(ApplicationContext context) + throws BeansException { + springCtx = context; + } + + public int getTimeOutMillis() { + return timeOutMillis; + } + + public void setTimeOutMillis(int timeOutMillis) { + this.timeOutMillis = timeOutMillis; + } + + public boolean isShuttingDown() { + return shuttingDown.get(); + } + + /** + * Update all camel beans to have autoStartup to false and handles quart + * workaround when JMX is disabled. + */ + @Override + public void postProcessBeanFactory( + ConfigurableListableBeanFactory beanFactory) throws BeansException { + for (CamelContext ctx : beanFactory.getBeansOfType(CamelContext.class) + .values()) { + ctx.setAutoStartup(false); + + if ((ctx instanceof DefaultCamelContext) + && (ctx.getManagementName() == null)) { + ((DefaultCamelContext) ctx).setManagementName(ctx.getName()); + } + } } } diff --git a/edexOsgi/com.raytheon.uf.edex.esb.camel/src/com/raytheon/uf/edex/esb/camel/context/DefaultContextStateManager.java b/edexOsgi/com.raytheon.uf.edex.esb.camel/src/com/raytheon/uf/edex/esb/camel/context/DefaultContextStateManager.java new file mode 100644 index 0000000000..e17a9e0701 --- /dev/null +++ b/edexOsgi/com.raytheon.uf.edex.esb.camel/src/com/raytheon/uf/edex/esb/camel/context/DefaultContextStateManager.java @@ -0,0 +1,215 @@ +/** + * 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.esb.camel.context; + +import java.util.EnumSet; +import java.util.Set; + +import org.apache.camel.CamelContext; +import org.apache.camel.Route; +import org.apache.camel.ServiceStatus; + +import com.raytheon.uf.edex.core.IContextStateProcessor; + +/** + * Implementation of IContextStateManager that does basic validation of context + * status as well as handling IContextStateProcessor for startup/shutdown of + * contexts. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Apr 10, 2014 2726       rjpeter     Initial creation
+ * 
+ * 
+ * + * @author rjpeter + * @version 1.0 + */ +public class DefaultContextStateManager implements IContextStateManager { + private static final Set STARTABLE_STATES = EnumSet.of( + ServiceStatus.Stopped, ServiceStatus.Suspended, + ServiceStatus.Suspending); + + private static final Set SUSPENDABLE_STATES = EnumSet.of( + ServiceStatus.Starting, ServiceStatus.Started); + + private static final Set STOPPABLE_STATES = EnumSet.of( + ServiceStatus.Starting, ServiceStatus.Started, + ServiceStatus.Suspending, ServiceStatus.Suspended); + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.edex.esb.camel.context.IContextStateManager# + * isContextStartable(org.apache.camel.CamelContext) + */ + @Override + public boolean isContextStartable(CamelContext context) throws Exception { + ServiceStatus status = context.getStatus(); + return STARTABLE_STATES.contains(status) + || (status.isStarted() && !context.isAutoStartup()); + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.edex.esb.camel.context.IContextStateManager#startContext + * (org.apache.camel.CamelContext) + */ + @Override + public boolean startContext(CamelContext context) throws Exception { + ServiceStatus status = context.getStatus(); + + boolean rval = status.isStarted(); + if (rval && !context.isAutoStartup()) { + for (Route route : context.getRoutes()) { + rval &= context.getRouteStatus(route.getId()).isStarted(); + } + } + + if (!rval) { + IContextStateProcessor processor = ContextManager.getInstance() + .getStateProcessor(context); + if (processor != null) { + processor.preStart(); + } + + context.start(); + rval = context.getStatus().isStarted(); + + /* + * if a context has autoStartup = false, all of its routes are + * started on the second time context.start is called, adding route + * check for future proofing just in case. + */ + if (!context.isAutoStartup()) { + for (Route route : context.getRoutes()) { + rval &= startRoute(route); + } + + /* + * clear the auto start up flag since its an initial condition + * only + */ + context.setAutoStartup(true); + } + + if (processor != null) { + processor.postStart(); + } + } + + return rval; + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.edex.esb.camel.context.IContextStateManager#startRoute + * (org.apache.camel.Route) + */ + @Override + public boolean startRoute(Route route) throws Exception { + String routeId = route.getId(); + CamelContext ctx = route.getRouteContext().getCamelContext(); + ServiceStatus status = ctx.getRouteStatus(routeId); + if (STARTABLE_STATES.contains(status)) { + ctx.startRoute(routeId); + status = ctx.getRouteStatus(routeId); + } + + return status.isStarted(); + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.edex.esb.camel.context.IContextStateManager# + * isContextStoppable (org.apache.camel.CamelContext) + */ + @Override + public boolean isContextStoppable(CamelContext context) throws Exception { + ServiceStatus status = context.getStatus(); + boolean shuttingDown = ContextManager.getInstance().isShuttingDown(); + return (shuttingDown && STOPPABLE_STATES.contains(status)) + || (!shuttingDown && SUSPENDABLE_STATES.contains(status)); + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.edex.esb.camel.context.IContextStateManager#stopContext + * (org.apache.camel.CamelContext) + */ + @Override + public boolean stopContext(CamelContext context) throws Exception { + ServiceStatus status = context.getStatus(); + if (isContextStoppable(context)) { + IContextStateProcessor processor = ContextManager.getInstance() + .getStateProcessor(context); + if (processor != null) { + processor.preStop(); + } + + // a context will automatically stop all its routes + if (ContextManager.getInstance().isShuttingDown()) { + context.stop(); + } else { + context.suspend(); + } + + if (processor != null) { + processor.postStop(); + } + + status = context.getStatus(); + } + + return status.isStopped(); + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.edex.esb.camel.context.IContextStateManager#stopRoute + * (org.apache.camel.Route) + */ + @Override + public boolean stopRoute(Route route) throws Exception { + String routeId = route.getId(); + CamelContext ctx = route.getRouteContext().getCamelContext(); + ServiceStatus status = ctx.getRouteStatus(routeId); + if (STOPPABLE_STATES.contains(status)) { + ctx.stopRoute(routeId); + status = ctx.getRouteStatus(routeId); + } + + return status.isStopped(); + } + +} diff --git a/edexOsgi/com.raytheon.uf.edex.esb.camel/src/com/raytheon/uf/edex/esb/camel/context/DependencyContextStateManager.java b/edexOsgi/com.raytheon.uf.edex.esb.camel/src/com/raytheon/uf/edex/esb/camel/context/DependencyContextStateManager.java new file mode 100644 index 0000000000..3fb03ddb69 --- /dev/null +++ b/edexOsgi/com.raytheon.uf.edex.esb.camel/src/com/raytheon/uf/edex/esb/camel/context/DependencyContextStateManager.java @@ -0,0 +1,229 @@ +/** + * 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.esb.camel.context; + +import java.util.LinkedList; +import java.util.List; +import java.util.Set; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Future; + +import org.apache.camel.CamelContext; +import org.apache.camel.Route; + +/** + * Implementation of IContextStateManager that handles dependencies between + * contexts so that contexts start/stop in the correct order. Can be given an + * ExecutorService to use to start/stop dependent contexts. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Apr 10, 2014 2726       rjpeter     Initial creation
+ * 
+ * 
+ * + * @author rjpeter + * @version 1.0 + */ +public class DependencyContextStateManager extends DefaultContextStateManager { + + /** + * Service to use to start/stop dependent contexts. If null, context + * processing will happen on current thread. + */ + protected final ExecutorService service; + + public DependencyContextStateManager() { + this(null); + } + + public DependencyContextStateManager(ExecutorService service) { + this.service = service; + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.edex.esb.camel.context.DefaultContextStateManager# + * isContextStartable(org.apache.camel.CamelContext) + */ + @Override + public boolean isContextStartable(CamelContext context) throws Exception { + if (!super.isContextStartable(context)) { + return false; + } + + Set requiredContexts = ContextManager.getInstance() + .getDependencyMapping(false).getRequiredContexts(context); + + if (requiredContexts != null) { + for (CamelContext rContext : requiredContexts) { + if (!rContext.getStatus().isStarted()) { + return false; + } else { + for (Route rRoute : rContext.getRoutes()) { + if (!rContext.getRouteStatus(rRoute.getId()) + .isStarted()) { + return false; + } + } + } + } + } + + return true; + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.edex.esb.camel.context.DefaultContextStateManager# + * startContext(org.apache.camel.CamelContext) + */ + @Override + public boolean startContext(CamelContext context) throws Exception { + boolean rval = super.startContext(context); + ContextManager ctxMgr = ContextManager.getInstance(); + + if (rval) { + Set dContexts = ctxMgr.getDependencyMapping(false) + .getDependentContexts(context); + if (dContexts != null) { + List> callbacks = null; + + for (final CamelContext dCtx : dContexts) { + final IContextStateManager stateMgr = ctxMgr + .getStateManager(dCtx); + if (stateMgr.isContextStartable(dCtx)) { + if (service != null) { + if (callbacks == null) { + callbacks = new LinkedList>(); + } + + callbacks.add(service + .submit(new Callable() { + @Override + public Boolean call() throws Exception { + return stateMgr.startContext(dCtx); + } + })); + } else { + stateMgr.startContext(dCtx); + } + } + } + + if (callbacks != null) { + for (Future callback : callbacks) { + rval &= callback.get().booleanValue(); + } + } + } + } + + return rval; + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.edex.esb.camel.context.DefaultContextStateManager# + * isContextStoppable(org.apache.camel.CamelContext) + */ + @Override + public boolean isContextStoppable(CamelContext context) throws Exception { + if (!super.isContextStoppable(context)) { + return false; + } + + Set dContexts = ContextManager.getInstance() + .getDependencyMapping(true).getDependentContexts(context); + + if (dContexts != null) { + for (CamelContext dContext : dContexts) { + /* + * only need to check if the context has stopped, can't have a + * stopped context with started routes. + */ + if (!dContext.getStatus().isStopped()) { + return false; + } + } + } + + return true; + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.edex.esb.camel.context.DefaultContextStateManager#stopContext + * (org.apache.camel.CamelContext) + */ + @Override + public boolean stopContext(CamelContext context) throws Exception { + boolean rval = super.stopContext(context); + ContextManager ctxMgr = ContextManager.getInstance(); + + if (rval) { + Set rContexts = ctxMgr.getDependencyMapping(true) + .getRequiredContexts(context); + if (rContexts != null) { + List> callbacks = null; + + for (final CamelContext rCtx : rContexts) { + final IContextStateManager stateMgr = ctxMgr + .getStateManager(rCtx); + if (stateMgr.isContextStoppable(rCtx)) { + if (service != null) { + if (callbacks == null) { + callbacks = new LinkedList>(); + } + + callbacks.add(service + .submit(new Callable() { + @Override + public Boolean call() throws Exception { + return stateMgr.stopContext(rCtx); + } + })); + } else { + stateMgr.stopContext(rCtx); + } + } + } + + if (callbacks != null) { + for (Future callback : callbacks) { + rval &= callback.get().booleanValue(); + } + } + } + } + + return rval; + } +} diff --git a/edexOsgi/com.raytheon.uf.edex.esb.camel/src/com/raytheon/uf/edex/esb/camel/context/DependencyNode.java b/edexOsgi/com.raytheon.uf.edex.esb.camel/src/com/raytheon/uf/edex/esb/camel/context/DependencyNode.java new file mode 100644 index 0000000000..be26ee88c4 --- /dev/null +++ b/edexOsgi/com.raytheon.uf.edex.esb.camel/src/com/raytheon/uf/edex/esb/camel/context/DependencyNode.java @@ -0,0 +1,145 @@ +/** + * 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.esb.camel.context; + +import java.util.HashSet; +import java.util.Set; + +import org.apache.camel.CamelContext; +import org.apache.camel.Endpoint; +import org.apache.camel.Route; + +import com.raytheon.uf.common.status.UFStatus; +import com.raytheon.uf.common.util.Pair; + +/** + * Class to map a context to its required and dependent contexts. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Apr 10, 2014 2726       rjpeter     Initial creation
+ * 
+ * 
+ * + * @author rjpeter + * @version 1.0 + */ +public class DependencyNode { + private final CamelContext context; + + /** + * Contexts required by this context. + */ + private final Set requiredContexs = new HashSet(); + + /** + * Contexts that depend on this context. + */ + private final Set dependentContexts = new HashSet(); + + public DependencyNode(CamelContext context) { + this.context = context; + } + + /** + * Add a node who is dependent on this node. Applies linking in both + * directions. + * + * @param dNode + */ + public void addDependentNode(DependencyNode dNode) { + if (!requiredContexs.contains(dNode.context)) { + dependentContexts.add(dNode.context); + dNode.requiredContexs.add(context); + } else { + StringBuilder msg = new StringBuilder(300); + msg.append("Circular CamelContext dependency detected between ") + .append(context.getName()) + .append(" and ") + .append(dNode.context.getName()) + .append(". Removing dependency, startup/shutdown may be incorrect, verify configuration. "); + addRouteData(context, msg); + addRouteData(dNode.context, msg); + UFStatus.getHandler(DependencyNode.class).warn(msg.toString()); + } + } + + public CamelContext getContext() { + return context; + } + + /** + * Get all contexts that this context requires to be running. + * + * @return + */ + public Set getRequiredContexts() { + return requiredContexs; + } + + /** + * Get all contexts that depend on this context to be running. + * + * @return + */ + public Set getDependentContexts() { + return dependentContexts; + } + + /** + * Utility method for printing information about a context. + * + * @param ctx + * @param builder + */ + private static void addRouteData(CamelContext ctx, StringBuilder builder) { + builder.append("Context [").append(ctx.getName()) + .append("] consumes from ["); + Set consumerEndpoints = new HashSet(); + for (Route route : ctx.getRoutes()) { + Endpoint endpoint = route.getEndpoint(); + String uri = endpoint.getEndpointUri(); + Pair typeAndName = ContextData + .getEndpointTypeAndName(uri); + String name = typeAndName.getFirst() + ":" + + typeAndName.getSecond(); + builder.append(name).append(", "); + consumerEndpoints.add(name); + } + builder.delete(builder.length() - 2, builder.length()); + builder.append("] and produces to ["); + for (Endpoint endpoint : ctx.getEndpoints()) { + String uri = endpoint.getEndpointUri(); + Pair typeAndName = ContextData + .getEndpointTypeAndName(uri); + String name = typeAndName.getFirst() + ":" + + typeAndName.getSecond(); + if (!consumerEndpoints.contains(name)) { + builder.append(name).append(", "); + } + } + builder.delete(builder.length() - 2, builder.length()); + builder.append("]. "); + } +} \ No newline at end of file diff --git a/edexOsgi/com.raytheon.uf.edex.esb.camel/src/com/raytheon/uf/edex/esb/camel/context/IContextStateManager.java b/edexOsgi/com.raytheon.uf.edex.esb.camel/src/com/raytheon/uf/edex/esb/camel/context/IContextStateManager.java new file mode 100644 index 0000000000..65c4409b66 --- /dev/null +++ b/edexOsgi/com.raytheon.uf.edex.esb.camel/src/com/raytheon/uf/edex/esb/camel/context/IContextStateManager.java @@ -0,0 +1,96 @@ +/** + * 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.esb.camel.context; + +import org.apache.camel.CamelContext; +import org.apache.camel.Route; + +/** + * Represents a way for managing a context for starting and stopping. Allows for + * Context with different purposes to be handled independently of each other. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Apr 10, 2014 2726       rjpeter     Initial creation.
+ * 
+ * 
+ * + * @author rjpeter + * @version 1.0 + */ +public interface IContextStateManager { + /** + * Is the {@code CamelContext} startable? + * + * @param context + * @return + * @throws Exception + */ + public boolean isContextStartable(CamelContext context) throws Exception; + + /** + * Start the {@code CamelContext}. + * + * @param context + * @return + * @throws Exception + */ + public boolean startContext(CamelContext context) throws Exception; + + /** + * Start the {@code Route}. + * + * @param context + * @return + * @throws Exception + */ + public boolean startRoute(Route route) throws Exception; + + /** + * Is the {@code CamelContext} stoppable? + * + * @param context + * @return + * @throws Exception + */ + public boolean isContextStoppable(CamelContext context) throws Exception; + + /** + * Stop the {@code CamelContext}. + * + * @param context + * @return + * @throws Exception + */ + public boolean stopContext(CamelContext context) throws Exception; + + /** + * Stop the {@code Route}. + * + * @param context + * @return + * @throws Exception + */ + public boolean stopRoute(Route route) throws Exception; +} \ No newline at end of file diff --git a/edexOsgi/com.raytheon.uf.edex.esb.camel/src/com/raytheon/uf/edex/esb/camel/directvm/DirectVMComponent.java b/edexOsgi/com.raytheon.uf.edex.esb.camel/src/com/raytheon/uf/edex/esb/camel/directvm/DirectVMComponent.java deleted file mode 100644 index 9d6324ecea..0000000000 --- a/edexOsgi/com.raytheon.uf.edex.esb.camel/src/com/raytheon/uf/edex/esb/camel/directvm/DirectVMComponent.java +++ /dev/null @@ -1,100 +0,0 @@ -/** - * 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.esb.camel.directvm; - -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; -import java.util.concurrent.CopyOnWriteArrayList; - -import org.apache.camel.Endpoint; -import org.apache.camel.component.direct.DirectComponent; -import org.apache.camel.impl.DefaultConsumer; -import org.apache.camel.impl.DefaultEndpoint; -import org.apache.camel.util.ServiceHelper; - -/** - * Provides a cross-context synchronous component. - * - *
- * 
- * SOFTWARE HISTORY
- * Date         Ticket#    Engineer    Description
- * ------------ ---------- ----------- --------------------------
- * Nov 18, 2008            chammack     Initial creation
- * Jul 16, 2012 DR 15073   D. Friedman  Don't stop all consumer in doStop.
- * May 23, 2013 1989       njensen      Deprecated
- * 
- * 
- * - * @author chammack - * @version 1.0 - * @deprecated Use camel's built-in direct-vm component instead. This component - * can be deleted after that has been tested thoroughly. - */ - -@SuppressWarnings("unchecked") -@Deprecated -public class DirectVMComponent extends DirectComponent { - - private static Map> CONSUMERS = new HashMap>(); - - @Override - protected Endpoint createEndpoint(String uri, String remaining, - Map parameters) throws Exception { - - synchronized (CONSUMERS) { - - CopyOnWriteArrayList consumers = CONSUMERS - .get(uri); - - if (consumers == null) { - consumers = new CopyOnWriteArrayList(); - CONSUMERS.put(uri, consumers); - - } - - Endpoint endpoint = new DirectVMEndpoint(uri, this, consumers); - setProperties(endpoint, parameters); - return endpoint; - } - - } - - @Override - protected void doStop() throws Exception { - Collection> set = CONSUMERS - .values(); - - /* - * Stop only the consumers created through this instance of the - * component. - */ - for (CopyOnWriteArrayList consumerList : set) - for (DefaultConsumer consumer : consumerList) { - Endpoint endpoint = consumer.getEndpoint(); - if (endpoint instanceof DefaultEndpoint) - if (((DefaultEndpoint) endpoint).getComponent() == this) - ServiceHelper.stopService(consumer); - } - - super.doStop(); - } -} diff --git a/edexOsgi/com.raytheon.uf.edex.esb.camel/src/com/raytheon/uf/edex/esb/camel/directvm/DirectVMEndpoint.java b/edexOsgi/com.raytheon.uf.edex.esb.camel/src/com/raytheon/uf/edex/esb/camel/directvm/DirectVMEndpoint.java deleted file mode 100644 index 975131b0fc..0000000000 --- a/edexOsgi/com.raytheon.uf.edex.esb.camel/src/com/raytheon/uf/edex/esb/camel/directvm/DirectVMEndpoint.java +++ /dev/null @@ -1,102 +0,0 @@ -/** - * 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.esb.camel.directvm; - -import java.util.List; -import java.util.concurrent.CopyOnWriteArrayList; - -import org.apache.camel.Consumer; -import org.apache.camel.Producer; -import org.apache.camel.component.direct.DirectEndpoint; -import org.apache.camel.impl.DefaultConsumer; - -/** - * - * Provides a cross-context synchronous component. - * - *
- * 
- * SOFTWARE HISTORY
- * Date         Ticket#    Engineer    Description
- * ------------ ---------- ----------- --------------------------
- * Nov 18, 2008            chammack     Initial creation
- * Jul 16, 2012 DR 15073   D. Friedman  Override correct methods
- * May 09, 2013 1989       njensen      Camel 2.11 compatibility
- * May 23, 2013 1989       njensen      Deprecated
- * 
- * 
- * - * @author chammack - * @version 1.0 - * @deprecated Use camel's built-in direct-vm component instead. This component - * can be deleted after that has been tested thoroughly. - */ - -@Deprecated -public class DirectVMEndpoint extends DirectEndpoint { - private boolean allowMultipleConsumers = true; - - private CopyOnWriteArrayList consumers = new CopyOnWriteArrayList(); - - public DirectVMEndpoint(String uri, DirectVMComponent component) { - super(uri, component); - } - - public DirectVMEndpoint(String uri, DirectVMComponent component, - CopyOnWriteArrayList consumers) { - super(uri, component); - this.consumers = consumers; - } - - @Override - public Producer createProducer() throws Exception { - return new DirectVMProducer(this); - } - - @Override - public Consumer createConsumer(org.apache.camel.Processor processor) - throws Exception { - return new DefaultConsumer(this, processor) { - @Override - protected void doStart() throws Exception { - if (!allowMultipleConsumers && !consumers.isEmpty()) { - throw new IllegalStateException( - "Endpoint " - + getEndpointUri() - + " only allows 1 active consumer but you attempted to start a 2nd consumer."); - } - - consumers.add(this); - super.doStart(); - } - - @Override - protected void doStop() throws Exception { - super.doStop(); - consumers.remove(this); - } - }; - } - - public List getConsumers() { - return consumers; - } - -} diff --git a/edexOsgi/com.raytheon.uf.edex.esb.camel/src/com/raytheon/uf/edex/esb/camel/directvm/DirectVMProducer.java b/edexOsgi/com.raytheon.uf.edex.esb.camel/src/com/raytheon/uf/edex/esb/camel/directvm/DirectVMProducer.java deleted file mode 100644 index 89f835147b..0000000000 --- a/edexOsgi/com.raytheon.uf.edex.esb.camel/src/com/raytheon/uf/edex/esb/camel/directvm/DirectVMProducer.java +++ /dev/null @@ -1,111 +0,0 @@ -/** - * 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.esb.camel.directvm; - -import java.util.List; - -import org.apache.camel.AsyncCallback; -import org.apache.camel.AsyncProcessor; -import org.apache.camel.CamelExchangeException; -import org.apache.camel.Exchange; -import org.apache.camel.component.direct.DirectProducer; -import org.apache.camel.impl.DefaultConsumer; -import org.apache.camel.impl.converter.AsyncProcessorTypeConverter; -import org.apache.camel.util.AsyncProcessorHelper; - -import com.raytheon.uf.common.status.IUFStatusHandler; -import com.raytheon.uf.common.status.UFStatus; -import com.raytheon.uf.common.status.UFStatus.Priority; - -/** - * Direct VM Producer used with DirectVMConsumer. - * - *
- * 
- * SOFTWARE HISTORY
- * 
- * Date         Ticket#    Engineer    Description
- * ------------ ---------- ----------- --------------------------
- * Oct 27, 2010            mschenke     Initial creation
- * May 23, 2013 1989       njensen      Deprecated
- * 
- * 
- * - * @author mschenke - * @version 1.0 - * @deprecated Use camel's built-in direct-vm component instead. This component - * can be deleted after that has been tested thoroughly. - */ - -@Deprecated -public class DirectVMProducer extends DirectProducer { - private static final transient IUFStatusHandler statusHandler = UFStatus - .getHandler(DirectVMProducer.class); - - private DirectVMEndpoint endpoint; - - /** - * @param endpoint - */ - public DirectVMProducer(DirectVMEndpoint endpoint) { - super(endpoint); - this.endpoint = endpoint; - } - - public void process(Exchange exchange) throws Exception { - List consumers = endpoint.getConsumers(); - if (consumers == null || consumers.size() == 0) { - statusHandler.handle(Priority.PROBLEM, - "No consumers available on endpoint: " + endpoint - + " to process: " + exchange); - throw new CamelExchangeException( - "No consumers available on endpoint: " + endpoint, exchange); - } else { - for (DefaultConsumer consumer : consumers) { - consumer.getProcessor().process(exchange); - } - } - } - - public boolean process(Exchange exchange, AsyncCallback callback) { - List consumers = endpoint.getConsumers(); - if (consumers == null || consumers.size() == 0) { - statusHandler.handle(Priority.PROBLEM, - "No consumers available on endpoint: " + endpoint - + " to process: " + exchange); - // indicate its done synchronously - exchange.setException(new CamelExchangeException( - "No consumers available on endpoint: " + endpoint, exchange)); - callback.done(true); - return true; - } else { - boolean sync = true; - for (DefaultConsumer consumer : consumers) { - AsyncProcessor processor = AsyncProcessorTypeConverter - .convert(consumer.getProcessor()); - sync &= AsyncProcessorHelper.process(processor, exchange, - callback); - } - - return sync; - } - } - -} diff --git a/edexOsgi/com.raytheon.uf.edex.esb.camel/src/com/raytheon/uf/edex/esb/camel/jms/DedicatedThreadJmsComponent.java b/edexOsgi/com.raytheon.uf.edex.esb.camel/src/com/raytheon/uf/edex/esb/camel/jms/DedicatedThreadJmsComponent.java index 978efdac8f..bd761c2b96 100644 --- a/edexOsgi/com.raytheon.uf.edex.esb.camel/src/com/raytheon/uf/edex/esb/camel/jms/DedicatedThreadJmsComponent.java +++ b/edexOsgi/com.raytheon.uf.edex.esb.camel/src/com/raytheon/uf/edex/esb/camel/jms/DedicatedThreadJmsComponent.java @@ -86,7 +86,6 @@ public class DedicatedThreadJmsComponent extends JmsComponent { executor.setMaxPoolSize(Math.max(jmsE.getConcurrentConsumers(), jmsE.getMaxConcurrentConsumers())); executor.setQueueCapacity(0); - executor.afterPropertiesSet(); jmsE.setTaskExecutor(executor); jmsE.setMessageListenerContainerFactory(MonitoredDefaultMessageListenerContainerFactory diff --git a/edexOsgi/com.raytheon.uf.edex.esb.camel/src/com/raytheon/uf/edex/esb/camel/spring/JmsThreadPoolTaskExecutor.java b/edexOsgi/com.raytheon.uf.edex.esb.camel/src/com/raytheon/uf/edex/esb/camel/spring/JmsThreadPoolTaskExecutor.java index f8e83f62eb..b0bfac85a5 100644 --- a/edexOsgi/com.raytheon.uf.edex.esb.camel/src/com/raytheon/uf/edex/esb/camel/spring/JmsThreadPoolTaskExecutor.java +++ b/edexOsgi/com.raytheon.uf.edex.esb.camel/src/com/raytheon/uf/edex/esb/camel/spring/JmsThreadPoolTaskExecutor.java @@ -19,6 +19,8 @@ **/ package com.raytheon.uf.edex.esb.camel.spring; +import java.util.concurrent.ThreadPoolExecutor; + import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; /** @@ -32,7 +34,7 @@ import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- * Nov 15, 2010 rjpeter Initial creation - * + * Apr 10, 2014 2726 rjpeter Updated to create/initialize the ThreadPoolExecutor on demand. * * * @author rjpeter @@ -40,6 +42,25 @@ import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; */ public class JmsThreadPoolTaskExecutor extends ThreadPoolTaskExecutor { + private static final long serialVersionUID = 1L; + + private volatile boolean needToInitialize = true; + + @Override + public ThreadPoolExecutor getThreadPoolExecutor() + throws IllegalStateException { + // don't initialize until first needed + if (needToInitialize) { + synchronized (this) { + if (needToInitialize) { + afterPropertiesSet(); + needToInitialize = false; + } + } + } + return super.getThreadPoolExecutor(); + } + @Override public boolean prefersShortLivedTasks() { return false; diff --git a/edexOsgi/com.raytheon.uf.edex.ingest/res/spring/persist-ingest.xml b/edexOsgi/com.raytheon.uf.edex.ingest/res/spring/persist-ingest.xml index e58c99323a..b14c671dbc 100644 --- a/edexOsgi/com.raytheon.uf.edex.ingest/res/spring/persist-ingest.xml +++ b/edexOsgi/com.raytheon.uf.edex.ingest/res/spring/persist-ingest.xml @@ -12,11 +12,11 @@ - + + - + @@ -41,9 +41,7 @@ - @@ -62,7 +60,7 @@ - + \ No newline at end of file diff --git a/edexOsgi/com.raytheon.uf.edex.ohd/res/spring/mpeLightningSrv-ingest.xml b/edexOsgi/com.raytheon.uf.edex.ohd/res/spring/mpeLightningSrv-ingest.xml index 2305af6fab..fe72681f62 100644 --- a/edexOsgi/com.raytheon.uf.edex.ohd/res/spring/mpeLightningSrv-ingest.xml +++ b/edexOsgi/com.raytheon.uf.edex.ohd/res/spring/mpeLightningSrv-ingest.xml @@ -9,7 +9,7 @@ + errorHandlerRef="errorHandler"> diff --git a/edexOsgi/com.raytheon.uf.edex.ohd/res/spring/satpre-spring.xml b/edexOsgi/com.raytheon.uf.edex.ohd/res/spring/satpre-spring.xml index 41b88edc54..73174adcd5 100644 --- a/edexOsgi/com.raytheon.uf.edex.ohd/res/spring/satpre-spring.xml +++ b/edexOsgi/com.raytheon.uf.edex.ohd/res/spring/satpre-spring.xml @@ -9,8 +9,7 @@ + errorHandlerRef="errorHandler"> @@ -27,8 +26,7 @@ - + \ No newline at end of file diff --git a/edexOsgi/com.raytheon.uf.edex.plugin.acars/res/spring/acars-ingest.xml b/edexOsgi/com.raytheon.uf.edex.plugin.acars/res/spring/acars-ingest.xml index e89bd76d0a..ab28897370 100644 --- a/edexOsgi/com.raytheon.uf.edex.plugin.acars/res/spring/acars-ingest.xml +++ b/edexOsgi/com.raytheon.uf.edex.plugin.acars/res/spring/acars-ingest.xml @@ -12,18 +12,10 @@ - - - - + errorHandlerRef="errorHandler"> + xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd"> diff --git a/edexOsgi/com.raytheon.uf.edex.plugin.manualIngest/res/spring/manualIngest-request.xml b/edexOsgi/com.raytheon.uf.edex.plugin.manualIngest/res/spring/manualIngest-request.xml index 411d4428a0..37d44e970e 100644 --- a/edexOsgi/com.raytheon.uf.edex.plugin.manualIngest/res/spring/manualIngest-request.xml +++ b/edexOsgi/com.raytheon.uf.edex.plugin.manualIngest/res/spring/manualIngest-request.xml @@ -8,7 +8,7 @@ - + diff --git a/edexOsgi/com.raytheon.uf.edex.plugin.manualIngest/res/spring/manualIngest-spring.xml b/edexOsgi/com.raytheon.uf.edex.plugin.manualIngest/res/spring/manualIngest-spring.xml index 0ec3a71073..af2f65b49b 100644 --- a/edexOsgi/com.raytheon.uf.edex.plugin.manualIngest/res/spring/manualIngest-spring.xml +++ b/edexOsgi/com.raytheon.uf.edex.plugin.manualIngest/res/spring/manualIngest-spring.xml @@ -6,7 +6,7 @@ + errorHandlerRef="errorHandler"> @@ -18,8 +18,7 @@ - + diff --git a/edexOsgi/com.raytheon.uf.edex.plugin.modelsounding/res/spring/modelsounding-ingest.xml b/edexOsgi/com.raytheon.uf.edex.plugin.modelsounding/res/spring/modelsounding-ingest.xml index 0a56c9b988..518b24d3c4 100644 --- a/edexOsgi/com.raytheon.uf.edex.plugin.modelsounding/res/spring/modelsounding-ingest.xml +++ b/edexOsgi/com.raytheon.uf.edex.plugin.modelsounding/res/spring/modelsounding-ingest.xml @@ -2,15 +2,12 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd"> - - + + class="com.raytheon.uf.edex.plugin.modelsounding.ModelSoundingDecoder"> @@ -25,11 +22,6 @@ - - - - @@ -45,10 +37,14 @@ + + + + + + errorHandlerRef="errorHandler"> + + + + + diff --git a/edexOsgi/com.raytheon.uf.edex.plugin.modelsounding/src/com/raytheon/uf/edex/plugin/modelsounding/ModelSoundingDecoder.java b/edexOsgi/com.raytheon.uf.edex.plugin.modelsounding/src/com/raytheon/uf/edex/plugin/modelsounding/ModelSoundingDecoder.java index 34dadeefe6..6492adfb5e 100644 --- a/edexOsgi/com.raytheon.uf.edex.plugin.modelsounding/src/com/raytheon/uf/edex/plugin/modelsounding/ModelSoundingDecoder.java +++ b/edexOsgi/com.raytheon.uf.edex.plugin.modelsounding/src/com/raytheon/uf/edex/plugin/modelsounding/ModelSoundingDecoder.java @@ -125,14 +125,6 @@ public class ModelSoundingDecoder extends AbstractDecoder implements } } - public void start() { - this.modelSoundingPersistenceManager.start(); - } - - public void shutdown() { - this.modelSoundingPersistenceManager.shutdown(); - } - /** * Get one entry from the separator and interpret that data as a single * profiler observation. 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 ca867f24d9..0528cd33c4 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 @@ -22,7 +22,6 @@ package com.raytheon.uf.edex.plugin.modelsounding; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; -import java.util.concurrent.atomic.AtomicBoolean; import com.raytheon.uf.common.dataplugin.PluginDataObject; import com.raytheon.uf.common.status.IUFStatusHandler; @@ -30,6 +29,7 @@ import com.raytheon.uf.common.status.UFStatus; import com.raytheon.uf.common.status.UFStatus.Priority; import com.raytheon.uf.edex.core.EDEXUtil; import com.raytheon.uf.edex.core.EdexException; +import com.raytheon.uf.edex.core.IContextStateProcessor; /** * Thread for storing Model Soundings asynchronously. If decode thread decodes @@ -42,40 +42,41 @@ import com.raytheon.uf.edex.core.EdexException; * * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- - * Jul 17, 2013 2161 bkowal Initial creation - * + * Jul 17, 2013 2161 bkowal Initial creation. + * Mar 11, 2014 2726 rjpeter Graceful shutdown. * * * @author bkowal * @version 1.0 */ -public class ModelSoundingPersistenceManager extends Thread { +public class ModelSoundingPersistenceManager implements IContextStateProcessor { /** The logger */ private final IUFStatusHandler logger = UFStatus .getHandler(ModelSoundingPersistenceManager.class); private final LinkedHashMap containerMap; - private final AtomicBoolean run = new AtomicBoolean(true); + private volatile boolean run = false; + + private volatile boolean shutdown = false; /** * */ public ModelSoundingPersistenceManager() { - super("ModelSoundingStore"); + // super("ModelSoundingStore"); this.containerMap = new LinkedHashMap( 64, 1); } - @Override public void run() { - boolean keepStoring = true; - while (keepStoring) { + run = true; + while (run) { try { ModelSoundingStorageContainer container = null; synchronized (containerMap) { - while (containerMap.isEmpty() && this.run.get()) { + while (containerMap.isEmpty() && run) { try { containerMap.wait(); } catch (InterruptedException e) { @@ -107,9 +108,6 @@ public class ModelSoundingPersistenceManager extends Thread { logger.error("Failed to persist " + pdos.length + " PluginDataObject(s)!", e); } - } else if (!this.run.get()) { - // received shutdown flag - keepStoring = false; } } catch (Throwable e) { // fail safe so store thread doesn't fail @@ -118,6 +116,24 @@ public class ModelSoundingPersistenceManager extends Thread { e); } } + + shutdown = true; + synchronized (containerMap) { + containerMap.notifyAll(); + } + } + + protected void storeContainer(ModelSoundingStorageContainer container) { + List pdoList = container.getPdos(); + PluginDataObject[] pdos = pdoList.toArray(new PluginDataObject[pdoList + .size()]); + try { + EDEXUtil.getMessageProducer().sendSync( + "modelSoundingPersistIndexAlert", pdos); + } catch (EdexException e) { + logger.error("Failed to persist " + pdos.length + + " PluginDataObject(s)!", e); + } } /** @@ -128,15 +144,15 @@ public class ModelSoundingPersistenceManager extends Thread { * * @param persistRecordKey * @param container - * @return */ - public boolean checkIn(String persistRecordKey, + public void checkIn(String persistRecordKey, ModelSoundingStorageContainer container) { - boolean rval = run.get(); + boolean storeLocal = true; synchronized (containerMap) { - if (rval) { + if (run) { ModelSoundingStorageContainer prev = containerMap.put( persistRecordKey, container); + storeLocal = false; if (prev != null) { // technically only possible in an environment where there // are multiple decode threads running, just append the @@ -151,7 +167,9 @@ public class ModelSoundingPersistenceManager extends Thread { } } - return rval; + if (storeLocal) { + storeContainer(container); + } } /** @@ -168,11 +186,34 @@ public class ModelSoundingPersistenceManager extends Thread { } } - public void shutdown() { - run.set(false); + @Override + public void preStart() { + } - synchronized (containerMap) { - containerMap.notify(); + @Override + public void postStart() { + } + + @Override + public void preStop() { + if (run) { + run = false; + + synchronized (containerMap) { + containerMap.notifyAll(); + + while (!shutdown) { + try { + containerMap.wait(1000); + } catch (Exception e) { + // ignore + } + } + } } } + + @Override + public void postStop() { + } } \ No newline at end of file diff --git a/edexOsgi/com.raytheon.uf.edex.plugin.npp.crimss/res/spring/crimss-ingest.xml b/edexOsgi/com.raytheon.uf.edex.plugin.npp.crimss/res/spring/crimss-ingest.xml index f40b7d96aa..e287dcda89 100644 --- a/edexOsgi/com.raytheon.uf.edex.plugin.npp.crimss/res/spring/crimss-ingest.xml +++ b/edexOsgi/com.raytheon.uf.edex.plugin.npp.crimss/res/spring/crimss-ingest.xml @@ -12,15 +12,9 @@ - - - - + errorHandlerRef="errorHandler"> diff --git a/edexOsgi/com.raytheon.uf.edex.plugin.npp.nucaps/res/spring/nucaps-ingest.xml b/edexOsgi/com.raytheon.uf.edex.plugin.npp.nucaps/res/spring/nucaps-ingest.xml index 063e071ff1..041d9eb20a 100644 --- a/edexOsgi/com.raytheon.uf.edex.plugin.npp.nucaps/res/spring/nucaps-ingest.xml +++ b/edexOsgi/com.raytheon.uf.edex.plugin.npp.nucaps/res/spring/nucaps-ingest.xml @@ -12,15 +12,9 @@ - - - - + errorHandlerRef="errorHandler"> diff --git a/edexOsgi/com.raytheon.uf.edex.plugin.npp.viirs/res/spring/viirs-ingest.xml b/edexOsgi/com.raytheon.uf.edex.plugin.npp.viirs/res/spring/viirs-ingest.xml index f32f770d16..f12f2a32ca 100644 --- a/edexOsgi/com.raytheon.uf.edex.plugin.npp.viirs/res/spring/viirs-ingest.xml +++ b/edexOsgi/com.raytheon.uf.edex.plugin.npp.viirs/res/spring/viirs-ingest.xml @@ -10,11 +10,6 @@ - - - - @@ -25,8 +20,7 @@ + errorHandlerRef="errorHandler"> diff --git a/edexOsgi/com.raytheon.uf.edex.plugin.obs.ogc/res/spring/obs-dpa-ingest.xml b/edexOsgi/com.raytheon.uf.edex.plugin.obs.ogc/res/spring/obs-dpa-ingest.xml index d1d3ef8623..0f849a3090 100644 --- a/edexOsgi/com.raytheon.uf.edex.plugin.obs.ogc/res/spring/obs-dpa-ingest.xml +++ b/edexOsgi/com.raytheon.uf.edex.plugin.obs.ogc/res/spring/obs-dpa-ingest.xml @@ -17,18 +17,11 @@ - - - - + errorHandlerRef="errorHandler"> diff --git a/edexOsgi/com.raytheon.uf.edex.plugin.obs.ogc/res/spring/obs-ogc-routes.xml b/edexOsgi/com.raytheon.uf.edex.plugin.obs.ogc/res/spring/obs-ogc-routes.xml index 22b4dd3a02..72600a2472 100644 --- a/edexOsgi/com.raytheon.uf.edex.plugin.obs.ogc/res/spring/obs-ogc-routes.xml +++ b/edexOsgi/com.raytheon.uf.edex.plugin.obs.ogc/res/spring/obs-ogc-routes.xml @@ -1,5 +1,5 @@ @@ -15,12 +15,6 @@ - - - - diff --git a/edexOsgi/com.raytheon.uf.edex.plugin.obs.ogc/res/spring/obs-ogc.xml b/edexOsgi/com.raytheon.uf.edex.plugin.obs.ogc/res/spring/obs-ogc.xml index 59b7ebee1d..58d73aa17e 100644 --- a/edexOsgi/com.raytheon.uf.edex.plugin.obs.ogc/res/spring/obs-ogc.xml +++ b/edexOsgi/com.raytheon.uf.edex.plugin.obs.ogc/res/spring/obs-ogc.xml @@ -1,7 +1,6 @@ + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd"> diff --git a/edexOsgi/com.raytheon.uf.edex.plugin.obs.registry/res/spring/obs-ogc-registry.xml b/edexOsgi/com.raytheon.uf.edex.plugin.obs.registry/res/spring/obs-ogc-registry.xml index 9853a10fed..c062cdca9d 100644 --- a/edexOsgi/com.raytheon.uf.edex.plugin.obs.registry/res/spring/obs-ogc-registry.xml +++ b/edexOsgi/com.raytheon.uf.edex.plugin.obs.registry/res/spring/obs-ogc-registry.xml @@ -27,12 +27,6 @@ - - - - diff --git a/edexOsgi/com.raytheon.uf.edex.plugin.preciprate/res/spring/preciprate-ingest.xml b/edexOsgi/com.raytheon.uf.edex.plugin.preciprate/res/spring/preciprate-ingest.xml index eb49a866b7..195e2ea75b 100644 --- a/edexOsgi/com.raytheon.uf.edex.plugin.preciprate/res/spring/preciprate-ingest.xml +++ b/edexOsgi/com.raytheon.uf.edex.plugin.preciprate/res/spring/preciprate-ingest.xml @@ -10,7 +10,7 @@
- + diff --git a/edexOsgi/com.raytheon.uf.edex.plugin.qc/res/spring/qc-ingest.xml b/edexOsgi/com.raytheon.uf.edex.plugin.qc/res/spring/qc-ingest.xml index 65dcbe6478..c5179f4a05 100644 --- a/edexOsgi/com.raytheon.uf.edex.plugin.qc/res/spring/qc-ingest.xml +++ b/edexOsgi/com.raytheon.uf.edex.plugin.qc/res/spring/qc-ingest.xml @@ -9,15 +9,9 @@
- - - - + errorHandlerRef="errorHandler"> diff --git a/edexOsgi/com.raytheon.uf.edex.plugin.qpf/res/spring/qpf-ingest.xml b/edexOsgi/com.raytheon.uf.edex.plugin.qpf/res/spring/qpf-ingest.xml index 2b90e0b133..d645e01cf0 100644 --- a/edexOsgi/com.raytheon.uf.edex.plugin.qpf/res/spring/qpf-ingest.xml +++ b/edexOsgi/com.raytheon.uf.edex.plugin.qpf/res/spring/qpf-ingest.xml @@ -10,7 +10,7 @@
- + diff --git a/edexOsgi/com.raytheon.uf.edex.plugin.satellite.mcidas/res/spring/satellite-mcidas-ingest.xml b/edexOsgi/com.raytheon.uf.edex.plugin.satellite.mcidas/res/spring/satellite-mcidas-ingest.xml index 988a5a7b45..d212f7ab03 100644 --- a/edexOsgi/com.raytheon.uf.edex.plugin.satellite.mcidas/res/spring/satellite-mcidas-ingest.xml +++ b/edexOsgi/com.raytheon.uf.edex.plugin.satellite.mcidas/res/spring/satellite-mcidas-ingest.xml @@ -11,15 +11,9 @@ - - - - + errorHandlerRef="errorHandler"> diff --git a/edexOsgi/com.raytheon.uf.edex.plugin.scan/res/spring/scan-ingest.xml b/edexOsgi/com.raytheon.uf.edex.plugin.scan/res/spring/scan-ingest.xml index 863ea586b8..0d52c3d8e0 100644 --- a/edexOsgi/com.raytheon.uf.edex.plugin.scan/res/spring/scan-ingest.xml +++ b/edexOsgi/com.raytheon.uf.edex.plugin.scan/res/spring/scan-ingest.xml @@ -23,10 +23,7 @@ - + @@ -41,8 +38,8 @@ - + + \ No newline at end of file diff --git a/edexOsgi/com.raytheon.uf.edex.plugin.svrwx/res/spring/svrwx-ingest.xml b/edexOsgi/com.raytheon.uf.edex.plugin.svrwx/res/spring/svrwx-ingest.xml index 58689cd836..d24cf70cee 100644 --- a/edexOsgi/com.raytheon.uf.edex.plugin.svrwx/res/spring/svrwx-ingest.xml +++ b/edexOsgi/com.raytheon.uf.edex.plugin.svrwx/res/spring/svrwx-ingest.xml @@ -13,15 +13,9 @@ - - - - + errorHandlerRef="errorHandler"> diff --git a/edexOsgi/com.raytheon.uf.edex.plugin.tcg/res/spring/tcg-ingest.xml b/edexOsgi/com.raytheon.uf.edex.plugin.tcg/res/spring/tcg-ingest.xml index 3a71efee64..5bec012152 100644 --- a/edexOsgi/com.raytheon.uf.edex.plugin.tcg/res/spring/tcg-ingest.xml +++ b/edexOsgi/com.raytheon.uf.edex.plugin.tcg/res/spring/tcg-ingest.xml @@ -13,15 +13,9 @@
- - - - + errorHandlerRef="errorHandler"> diff --git a/edexOsgi/com.raytheon.uf.edex.plugin.tcs/res/spring/tcs-ingest.xml b/edexOsgi/com.raytheon.uf.edex.plugin.tcs/res/spring/tcs-ingest.xml index c6fd1f8d32..1c9610a805 100644 --- a/edexOsgi/com.raytheon.uf.edex.plugin.tcs/res/spring/tcs-ingest.xml +++ b/edexOsgi/com.raytheon.uf.edex.plugin.tcs/res/spring/tcs-ingest.xml @@ -13,15 +13,9 @@
- - - - + errorHandlerRef="errorHandler"> diff --git a/edexOsgi/com.raytheon.uf.edex.plugin.vaa/res/spring/vaa-ingest.xml b/edexOsgi/com.raytheon.uf.edex.plugin.vaa/res/spring/vaa-ingest.xml index 2bb0092618..171ec133b1 100644 --- a/edexOsgi/com.raytheon.uf.edex.plugin.vaa/res/spring/vaa-ingest.xml +++ b/edexOsgi/com.raytheon.uf.edex.plugin.vaa/res/spring/vaa-ingest.xml @@ -11,15 +11,9 @@
- - - - + errorHandlerRef="errorHandler"> + errorHandlerRef="errorHandler"> @@ -54,8 +54,7 @@ - + \ No newline at end of file diff --git a/edexOsgi/com.raytheon.uf.edex.textdbsrv/res/spring/textdbsrv-request.xml b/edexOsgi/com.raytheon.uf.edex.textdbsrv/res/spring/textdbsrv-request.xml index d0bbfc2f79..73917fc0e1 100644 --- a/edexOsgi/com.raytheon.uf.edex.textdbsrv/res/spring/textdbsrv-request.xml +++ b/edexOsgi/com.raytheon.uf.edex.textdbsrv/res/spring/textdbsrv-request.xml @@ -4,10 +4,10 @@ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd"> - + - + diff --git a/edexOsgi/com.raytheon.uf.edex.wfs/res/spring/wfs-ogc-soap-request.xml b/edexOsgi/com.raytheon.uf.edex.wfs/res/spring/wfs-ogc-soap-request.xml index 67649049c1..dc7b1299f8 100644 --- a/edexOsgi/com.raytheon.uf.edex.wfs/res/spring/wfs-ogc-soap-request.xml +++ b/edexOsgi/com.raytheon.uf.edex.wfs/res/spring/wfs-ogc-soap-request.xml @@ -1,10 +1,8 @@ + http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.0.xsd"> diff --git a/ncep/gov.noaa.nws.ncep.edex.common/res/spring/ncinventory-request.xml b/ncep/gov.noaa.nws.ncep.edex.common/res/spring/ncinventory-request.xml index 5ed9a3a3d2..9a753329d9 100644 --- a/ncep/gov.noaa.nws.ncep.edex.common/res/spring/ncinventory-request.xml +++ b/ncep/gov.noaa.nws.ncep.edex.common/res/spring/ncinventory-request.xml @@ -25,15 +25,16 @@ - - - - + + + errorHandlerRef="errorHandler"> + + + + + @@ -72,17 +73,4 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/ncep/gov.noaa.nws.ncep.edex.ingest.grib.util/res/spring/ncep-util-on-edex-ingestGrib.xml b/ncep/gov.noaa.nws.ncep.edex.ingest.grib.util/res/spring/ncep-util-on-edex-ingestGrib.xml index fd81e95b04..9e2b603312 100644 --- a/ncep/gov.noaa.nws.ncep.edex.ingest.grib.util/res/spring/ncep-util-on-edex-ingestGrib.xml +++ b/ncep/gov.noaa.nws.ncep.edex.ingest.grib.util/res/spring/ncep-util-on-edex-ingestGrib.xml @@ -1,8 +1,7 @@ + xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd"> diff --git a/ncep/gov.noaa.nws.ncep.edex.ingest.util/res/spring/ncep-util-on-edex-ingest.xml b/ncep/gov.noaa.nws.ncep.edex.ingest.util/res/spring/ncep-util-on-edex-ingest.xml index 1bb57bd273..94f4f216ce 100644 --- a/ncep/gov.noaa.nws.ncep.edex.ingest.util/res/spring/ncep-util-on-edex-ingest.xml +++ b/ncep/gov.noaa.nws.ncep.edex.ingest.util/res/spring/ncep-util-on-edex-ingest.xml @@ -1,8 +1,7 @@ + xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd"> diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.airep/res/spring/airep-ingest.xml b/ncep/gov.noaa.nws.ncep.edex.plugin.airep/res/spring/airep-ingest.xml index b627390977..2ad9e217a2 100644 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.airep/res/spring/airep-ingest.xml +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.airep/res/spring/airep-ingest.xml @@ -16,16 +16,10 @@ - - - - + errorHandlerRef="errorHandler"> diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.aww/res/spring/aww-ingest.xml b/ncep/gov.noaa.nws.ncep.edex.plugin.aww/res/spring/aww-ingest.xml index 42922eb7d5..3addea8068 100644 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.aww/res/spring/aww-ingest.xml +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.aww/res/spring/aww-ingest.xml @@ -27,15 +27,9 @@ - - - - + errorHandlerRef="errorHandler"> diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.convsigmet/res/spring/convsigmet-ingest.xml b/ncep/gov.noaa.nws.ncep.edex.plugin.convsigmet/res/spring/convsigmet-ingest.xml index d4bbbbd516..0325113a3e 100644 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.convsigmet/res/spring/convsigmet-ingest.xml +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.convsigmet/res/spring/convsigmet-ingest.xml @@ -16,15 +16,9 @@ - - - - + errorHandlerRef="errorHandler"> diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.gpd/res/spring/gpd-common.xml b/ncep/gov.noaa.nws.ncep.edex.plugin.gpd/res/spring/gpd-common.xml index aabd160479..d3449b6f8b 100644 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.gpd/res/spring/gpd-common.xml +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.gpd/res/spring/gpd-common.xml @@ -1,7 +1,6 @@ + xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd"> diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.gpd/res/spring/gpd-request.xml b/ncep/gov.noaa.nws.ncep.edex.plugin.gpd/res/spring/gpd-request.xml index 3c74e5713e..626214480f 100644 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.gpd/res/spring/gpd-request.xml +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.gpd/res/spring/gpd-request.xml @@ -1,8 +1,6 @@ + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd"> diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.idft/res/spring/idft-ingest.xml b/ncep/gov.noaa.nws.ncep.edex.plugin.idft/res/spring/idft-ingest.xml index 41ded2bf76..2b2abc547f 100644 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.idft/res/spring/idft-ingest.xml +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.idft/res/spring/idft-ingest.xml @@ -16,14 +16,8 @@ - - - - + errorHandlerRef="errorHandler"> diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.intlsigmet/res/spring/intlsigmet-ingest.xml b/ncep/gov.noaa.nws.ncep.edex.plugin.intlsigmet/res/spring/intlsigmet-ingest.xml index 352d79ccc2..b0c2197d99 100644 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.intlsigmet/res/spring/intlsigmet-ingest.xml +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.intlsigmet/res/spring/intlsigmet-ingest.xml @@ -15,15 +15,9 @@ - - - - + errorHandlerRef="errorHandler"> diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.mosaic/res/spring/mosaic-ingest.xml b/ncep/gov.noaa.nws.ncep.edex.plugin.mosaic/res/spring/mosaic-ingest.xml index 32178b148c..4a409932ab 100644 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.mosaic/res/spring/mosaic-ingest.xml +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.mosaic/res/spring/mosaic-ingest.xml @@ -26,15 +26,9 @@ - - - - + errorHandlerRef="errorHandler"> diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.ncgrib/res/spring/ncgrib-file-endpoint.xml b/ncep/gov.noaa.nws.ncep.edex.plugin.ncgrib/res/spring/ncgrib-file-endpoint.xml index dc319c9a43..e364db945b 100644 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.ncgrib/res/spring/ncgrib-file-endpoint.xml +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.ncgrib/res/spring/ncgrib-file-endpoint.xml @@ -6,8 +6,7 @@ + errorHandlerRef="errorHandler"> @@ -23,8 +22,7 @@ - + diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.ncpafm/res/spring/ncpafm-ingest.xml b/ncep/gov.noaa.nws.ncep.edex.plugin.ncpafm/res/spring/ncpafm-ingest.xml index 902d9bf772..5c3c4fa725 100644 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.ncpafm/res/spring/ncpafm-ingest.xml +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.ncpafm/res/spring/ncpafm-ingest.xml @@ -18,14 +18,8 @@ - - - - + errorHandlerRef="errorHandler"> diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.ncscd/res/spring/ncscd-ingest.xml b/ncep/gov.noaa.nws.ncep.edex.plugin.ncscd/res/spring/ncscd-ingest.xml index 6b3ddfa68c..044cfc43ba 100644 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.ncscd/res/spring/ncscd-ingest.xml +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.ncscd/res/spring/ncscd-ingest.xml @@ -26,13 +26,8 @@ - - - - + errorHandlerRef="errorHandler"> diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.nctaf/res/spring/nctaf-ingest.xml b/ncep/gov.noaa.nws.ncep.edex.plugin.nctaf/res/spring/nctaf-ingest.xml index 0cc91f22cb..bb46c904c1 100644 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.nctaf/res/spring/nctaf-ingest.xml +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.nctaf/res/spring/nctaf-ingest.xml @@ -15,15 +15,9 @@
- - - - + errorHandlerRef="errorHandler"> diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.nonconvsigmet/res/spring/nonconvsigmet-ingest.xml b/ncep/gov.noaa.nws.ncep.edex.plugin.nonconvsigmet/res/spring/nonconvsigmet-ingest.xml index caa82e2c84..632ad8f69f 100644 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.nonconvsigmet/res/spring/nonconvsigmet-ingest.xml +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.nonconvsigmet/res/spring/nonconvsigmet-ingest.xml @@ -16,15 +16,9 @@
- - - - + errorHandlerRef="errorHandler"> diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.pirep/res/spring/pirep-ingest.xml b/ncep/gov.noaa.nws.ncep.edex.plugin.pirep/res/spring/pirep-ingest.xml index 965e56bc2d..e6f754099a 100644 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.pirep/res/spring/pirep-ingest.xml +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.pirep/res/spring/pirep-ingest.xml @@ -18,14 +18,8 @@
- - - - + errorHandlerRef="errorHandler"> diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.sgwhv/res/spring/sgwhv-ingest.xml b/ncep/gov.noaa.nws.ncep.edex.plugin.sgwhv/res/spring/sgwhv-ingest.xml index 52c60fae23..1f2760e60c 100644 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.sgwhv/res/spring/sgwhv-ingest.xml +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.sgwhv/res/spring/sgwhv-ingest.xml @@ -21,15 +21,9 @@
- - - - + errorHandlerRef="errorHandler"> diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.solarimage/res/spring/solarimage-ingest.xml b/ncep/gov.noaa.nws.ncep.edex.plugin.solarimage/res/spring/solarimage-ingest.xml index f6b5665de9..5608a288f1 100644 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.solarimage/res/spring/solarimage-ingest.xml +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.solarimage/res/spring/solarimage-ingest.xml @@ -18,18 +18,12 @@
- - - - + errorHandlerRef="errorHandler"> diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.ssha/res/spring/ssha-ingest.xml b/ncep/gov.noaa.nws.ncep.edex.plugin.ssha/res/spring/ssha-ingest.xml index 0abc5a6fe8..812701dc22 100644 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.ssha/res/spring/ssha-ingest.xml +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.ssha/res/spring/ssha-ingest.xml @@ -22,15 +22,9 @@
- - - - + errorHandlerRef="errorHandler"> diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.stormtrack/res/spring/stormtrack-ingest.xml b/ncep/gov.noaa.nws.ncep.edex.plugin.stormtrack/res/spring/stormtrack-ingest.xml index aa1f96f9a9..ff59eea2d5 100644 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.stormtrack/res/spring/stormtrack-ingest.xml +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.stormtrack/res/spring/stormtrack-ingest.xml @@ -23,14 +23,8 @@
- - - - + errorHandlerRef="errorHandler"> diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.tcm/res/spring/tcm-ingest.xml b/ncep/gov.noaa.nws.ncep.edex.plugin.tcm/res/spring/tcm-ingest.xml index ed77155176..2fae466e6a 100644 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.tcm/res/spring/tcm-ingest.xml +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.tcm/res/spring/tcm-ingest.xml @@ -16,14 +16,8 @@
- - - - + errorHandlerRef="errorHandler"> diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.wcp/res/spring/wcp-ingest.xml b/ncep/gov.noaa.nws.ncep.edex.plugin.wcp/res/spring/wcp-ingest.xml index b9589deea9..0617dd0d46 100644 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.wcp/res/spring/wcp-ingest.xml +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.wcp/res/spring/wcp-ingest.xml @@ -16,14 +16,8 @@
- - - - + errorHandlerRef="errorHandler"> diff --git a/ost/gov.noaa.nws.ost.edex.plugin.regionalsat/res/spring/regionalsat-ingest.xml b/ost/gov.noaa.nws.ost.edex.plugin.regionalsat/res/spring/regionalsat-ingest.xml index ff0a2d8eea..89da5f5eca 100644 --- a/ost/gov.noaa.nws.ost.edex.plugin.regionalsat/res/spring/regionalsat-ingest.xml +++ b/ost/gov.noaa.nws.ost.edex.plugin.regionalsat/res/spring/regionalsat-ingest.xml @@ -16,15 +16,9 @@ - - - - + errorHandlerRef="errorHandler"> diff --git a/tools/scripts/commit-msg b/tools/scripts/commit-msg old mode 100644 new mode 100755 diff --git a/tools/scripts/git-u-setup b/tools/scripts/git-u-setup old mode 100644 new mode 100755 diff --git a/tools/scripts/uamend b/tools/scripts/uamend old mode 100644 new mode 100755 diff --git a/tools/scripts/ucommit b/tools/scripts/ucommit old mode 100644 new mode 100755 diff --git a/tools/scripts/upull b/tools/scripts/upull old mode 100644 new mode 100755 diff --git a/tools/scripts/upush b/tools/scripts/upush old mode 100644 new mode 100755 diff --git a/tools/scripts/ustat b/tools/scripts/ustat old mode 100644 new mode 100755