diff --git a/edexOsgi/com.raytheon.uf.common.registry.ebxml/src/com/raytheon/uf/common/registry/constants/RegistryAvailability.java b/edexOsgi/com.raytheon.uf.common.registry.ebxml/src/com/raytheon/uf/common/registry/constants/RegistryAvailability.java index 7a4acb1a14..1e1e796605 100644 --- a/edexOsgi/com.raytheon.uf.common.registry.ebxml/src/com/raytheon/uf/common/registry/constants/RegistryAvailability.java +++ b/edexOsgi/com.raytheon.uf.common.registry.ebxml/src/com/raytheon/uf/common/registry/constants/RegistryAvailability.java @@ -43,4 +43,6 @@ public class RegistryAvailability { /** Registry not available since the database is not yet initialized */ public static final String DB_NOT_INITIALIZED = "Registry database and services are currently initializing!"; + + public static final String SYNC_IN_PROGRESS = "Registry currently being synchronized"; } diff --git a/edexOsgi/com.raytheon.uf.edex.datadelivery.registry/src/com/raytheon/uf/edex/datadelivery/registry/dao/ReplicationEventDao.java b/edexOsgi/com.raytheon.uf.edex.datadelivery.registry/src/com/raytheon/uf/edex/datadelivery/registry/dao/ReplicationEventDao.java index 96f75328e9..05e5bfab7e 100644 --- a/edexOsgi/com.raytheon.uf.edex.datadelivery.registry/src/com/raytheon/uf/edex/datadelivery/registry/dao/ReplicationEventDao.java +++ b/edexOsgi/com.raytheon.uf.edex.datadelivery.registry/src/com/raytheon/uf/edex/datadelivery/registry/dao/ReplicationEventDao.java @@ -53,8 +53,8 @@ public class ReplicationEventDao extends } @Transactional(propagation = Propagation.MANDATORY, readOnly = true) - public List getReplicationEvents(String remoteRegistry) { + public List getReplicationEvents(String remoteRegistry, int batchSize) { return this.executeHQLQuery(String.format(GET_REPLICATION_EVENT_QUERY, - remoteRegistry, remoteRegistry)); + remoteRegistry, remoteRegistry),batchSize); } } diff --git a/edexOsgi/com.raytheon.uf.edex.datadelivery.registry/src/com/raytheon/uf/edex/datadelivery/registry/federation/RegistryFederationManager.java b/edexOsgi/com.raytheon.uf.edex.datadelivery.registry/src/com/raytheon/uf/edex/datadelivery/registry/federation/RegistryFederationManager.java index ae1236c060..b13025707f 100644 --- a/edexOsgi/com.raytheon.uf.edex.datadelivery.registry/src/com/raytheon/uf/edex/datadelivery/registry/federation/RegistryFederationManager.java +++ b/edexOsgi/com.raytheon.uf.edex.datadelivery.registry/src/com/raytheon/uf/edex/datadelivery/registry/federation/RegistryFederationManager.java @@ -104,7 +104,6 @@ import com.raytheon.uf.edex.registry.ebxml.dao.DbInit; import com.raytheon.uf.edex.registry.ebxml.dao.RegistryDao; import com.raytheon.uf.edex.registry.ebxml.dao.RegistryObjectDao; import com.raytheon.uf.edex.registry.ebxml.exception.EbxmlRegistryException; -import com.raytheon.uf.edex.registry.ebxml.exception.NoReplicationServersAvailableException; import com.raytheon.uf.edex.registry.ebxml.init.RegistryInitializedListener; import com.raytheon.uf.edex.registry.ebxml.services.query.QueryConstants; import com.raytheon.uf.edex.registry.ebxml.services.query.RegistryQueryUtil; @@ -153,6 +152,7 @@ import com.raytheon.uf.edex.registry.events.CreateAuditTrailEvent; * 1/21/2014 2613 bphillip Changed max down time which requires a sync * Feb 11, 2014 2771 bgonzale Use Data Delivery ID instead of Site. * 2/13/2014 2769 bphillip Refactored registry sync. Created quartz tasks to monitor registry uptime as well as subscription integrity + * 4/11/2014 3011 bphillip Removed automatic registry sync check on startup * * * @author bphillip @@ -167,6 +167,9 @@ public class RegistryFederationManager implements IRegistryFederationManager, protected static final IUFStatusHandler statusHandler = UFStatus .getHandler(RegistryFederationManager.class); + private static final transient IUFStatusHandler monitorHandler = UFStatus + .getMonitorHandler(RegistryFederationManager.class); + /** Query used for synchronizing registries */ private static final String SYNC_QUERY = "FROM RegistryObjectType obj where obj.id in (%s) order by obj.id asc"; @@ -196,7 +199,16 @@ public class RegistryFederationManager implements IRegistryFederationManager, * The maximum time a registry can be down before a full synchronization is * performed */ - private static final long MAX_DOWN_TIME_DURATION = TimeUtil.MILLIS_PER_HOUR * 6; + private static final long MAX_DOWN_TIME_DURATION = TimeUtil.MILLIS_PER_HOUR * 48; + + private static final String SYNC_WARNING_MSG = "Registry is out of sync with federation. Registry Synchronization required. Go to: [" + + RegistryUtil.LOCAL_REGISTRY_ADDRESS + + "/registry/federation/status.html] to synchronize."; + + private static volatile boolean SYNC_NECESSARY = false; + + public static AtomicBoolean SYNC_IN_PROGRESS = new AtomicBoolean( + false); /** Cutoff parameter for the query to get the expired events */ private static final String GET_EXPIRED_EVENTS_QUERY_CUTOFF_PARAMETER = "cutoff"; @@ -205,9 +217,6 @@ public class RegistryFederationManager implements IRegistryFederationManager, private static final String GET_EXPIRED_EVENTS_QUERY = "FROM ReplicationEvent event where event.eventTime < :" + GET_EXPIRED_EVENTS_QUERY_CUTOFF_PARAMETER; - /** Maximum times this registry will try to sync data before failure */ - private int maxSyncRetries = 3; - /** * Denotes if initialization has already occurred for this class. It is a * static variable because at this time, multiple Spring containers load @@ -320,8 +329,6 @@ public class RegistryFederationManager implements IRegistryFederationManager, if (!centralRegistry) { checkDownTime(); } - federatedRegistryMonitor.updateTime(); - } catch (Exception e1) { throw new EbxmlRegistryException( "Error initializing RegistryReplicationManager", e1); @@ -345,96 +352,24 @@ public class RegistryFederationManager implements IRegistryFederationManager, /** * Checks how long a registry has been down. If the registry has been down - * for over 2 days, the registry is synchronized with one of the federation - * members + * longer than the MAX_DOWN_TIME_DURATION, then a sync is necessary * + * @see RegistryFederationManager.MAX_DOWN_TIME_DURATION * @throws Exception */ private void checkDownTime() throws Exception { long currentTime = TimeUtil.currentTimeMillis(); long lastKnownUp = federatedRegistryMonitor.getLastKnownUptime(); long downTime = currentTime - lastKnownUp; - statusHandler - .info("Registry has been down since: " - + new Date(currentTime - downTime) - + ". Checking if synchronization with the federation is necessary..."); - - // The registry has been down for ~2 days, this requires a - // synchronization of the - // data from the federation + statusHandler.info("Registry has been down since: " + + new Date(currentTime - downTime)); + /* + * The registry has been down for ~2 days, this requires a + * synchronization of the data from the federation + */ if (currentTime - lastKnownUp > MAX_DOWN_TIME_DURATION) { - int syncAttempt = 1; - for (; syncAttempt <= maxSyncRetries; syncAttempt++) { - try { - statusHandler - .warn("Registry has been down for more than " - + (MAX_DOWN_TIME_DURATION / TimeUtil.MILLIS_PER_HOUR) - + " hours. Initiating federated registry data synchronization attempt #" - + syncAttempt + "/" + maxSyncRetries - + "..."); - if (CollectionUtil.isNullOrEmpty(servers - .getRegistryReplicationServers())) { - statusHandler - .error("No servers configured for replication. Unable to synchronize registry data with federation!"); - break; - } else { - RegistryType registryToSyncFrom = null; - for (String remoteRegistryId : servers - .getRegistryReplicationServers()) { - statusHandler.info("Checking availability of [" - + remoteRegistryId + "]..."); - RegistryType remoteRegistry = dataDeliveryRestClient - .getRegistryObject( - ncfAddress, - remoteRegistryId - + FederationProperties.REGISTRY_SUFFIX); - if (remoteRegistry == null) { - statusHandler - .warn("Registry at [" - + remoteRegistryId - + "] not found in federation. Unable to use as synchronization source."); - } else if (dataDeliveryRestClient - .isRegistryAvailable(remoteRegistry - .getBaseURL())) { - registryToSyncFrom = remoteRegistry; - break; - } else { - statusHandler - .info("Registry at [" - + remoteRegistryId - + "] is not available. Unable to use as synchronization source."); - } - } - - // No available registry was found! - if (registryToSyncFrom == null) { - throw new NoReplicationServersAvailableException( - "No available registries found! Registry data will not be synchronized with the federation!"); - } else { - synchronizeWithRegistry(registryToSyncFrom.getId()); - - break; - } - } - } catch (Exception e) { - // If no servers are found, don't retry, just throw the - // exception - if (e instanceof NoReplicationServersAvailableException) { - throw e; - } - if (syncAttempt < maxSyncRetries) { - statusHandler.error( - "Federation registry data synchronization attempt #" - + syncAttempt + "/" + maxSyncRetries - + " failed! Retrying...", e); - } else { - statusHandler - .fatal("Federation registry data synchronization has failed", - e); - throw e; - } - } - } + SYNC_NECESSARY = true; + sendSyncMessage(); } } @@ -586,33 +521,51 @@ public class RegistryFederationManager implements IRegistryFederationManager, @Transactional @GET @Path("synchronizeWithRegistry/{registryId}") - public void synchronizeWithRegistry( - @PathParam("registryId") String registryId) throws Exception { - long start = TimeUtil.currentTimeMillis(); - RegistryType remoteRegistry = null; - try { - if (!registryId.endsWith(FederationProperties.REGISTRY_SUFFIX)) { - registryId += FederationProperties.REGISTRY_SUFFIX; - } - remoteRegistry = dataDeliveryRestClient.getRegistryObject( - ncfAddress, registryId); - } catch (Exception e) { - throw new EbxmlRegistryException( - "Error retrieving info for remote registry [" + registryId - + "] ", e); - } - if (remoteRegistry == null) { - throw new EbxmlRegistryException("Unable to synchronize with [" - + registryId + "]. Registry not found in federation"); - } - String remoteRegistryUrl = remoteRegistry.getBaseURL(); + public void synchronizeWithRegistry(@PathParam("registryId") + String registryId) throws Exception { + if (SYNC_IN_PROGRESS.compareAndSet(false, true)) { + try { + monitorHandler.handle(Priority.WARN, + "Synchronizing registry with [" + registryId + "]..."); + long start = TimeUtil.currentTimeMillis(); + RegistryType remoteRegistry = null; + try { + if (!registryId + .endsWith(FederationProperties.REGISTRY_SUFFIX)) { + registryId += FederationProperties.REGISTRY_SUFFIX; + } + remoteRegistry = dataDeliveryRestClient.getRegistryObject( + ncfAddress, registryId); + } catch (Exception e) { + throw new EbxmlRegistryException( + "Error retrieving info for remote registry [" + + registryId + "] ", e); + } + if (remoteRegistry == null) { + throw new EbxmlRegistryException( + "Unable to synchronize with [" + registryId + + "]. Registry not found in federation"); + } + String remoteRegistryUrl = remoteRegistry.getBaseURL(); - for (final String objectType : replicatedObjectTypes) { - syncObjectType(objectType, remoteRegistryUrl); + for (final String objectType : replicatedObjectTypes) { + syncObjectType(objectType, remoteRegistryUrl); + } + SYNC_NECESSARY = false; + federatedRegistryMonitor.updateTime(); + StringBuilder syncMsg = new StringBuilder(); + + syncMsg.append("Registry synchronization using [") + .append(remoteRegistryUrl) + .append("] completed successfully in ") + .append((TimeUtil.currentTimeMillis() - start)) + .append(" ms"); + statusHandler.info(syncMsg.toString()); + monitorHandler.handle(Priority.WARN, syncMsg.toString()); + } finally { + SYNC_IN_PROGRESS.set(false); + } } - statusHandler.info("Registry synchronization using [" - + remoteRegistryUrl + "] completed successfully in " - + (TimeUtil.currentTimeMillis() - start) + " ms"); } /** @@ -658,6 +611,8 @@ public class RegistryFederationManager implements IRegistryFederationManager, int remainder = remoteIds.size() % SYNC_BATCH_SIZE; for (int currentBatch = 0; currentBatch < batches; currentBatch++) { + statusHandler.info("Processing batch " + (currentBatch + 1) + + "/" + batches); persistBatch(objectType, remoteRegistryUrl, remoteIds.subList( currentBatch * SYNC_BATCH_SIZE, (currentBatch + 1) * SYNC_BATCH_SIZE)); @@ -714,6 +669,13 @@ public class RegistryFederationManager implements IRegistryFederationManager, } } + private void sendSyncMessage() { + if (!SYNC_IN_PROGRESS.get()) { + statusHandler.warn(SYNC_WARNING_MSG); + monitorHandler.handle(Priority.WARN, SYNC_WARNING_MSG); + } + } + @GET @Path("isFederated") @Transactional @@ -795,8 +757,8 @@ public class RegistryFederationManager implements IRegistryFederationManager, @GET @Path("subscribeToRegistry/{registryId}") @Transactional - public void subscribeToRegistry(@PathParam("registryId") String registryId) - throws Exception { + public void subscribeToRegistry(@PathParam("registryId") + String registryId) throws Exception { statusHandler.info("Establishing replication with [" + registryId + "]..."); RegistryType remoteRegistry = getRegistry(registryId); @@ -809,8 +771,8 @@ public class RegistryFederationManager implements IRegistryFederationManager, @GET @Path("unsubscribeFromRegistry/{registryId}") @Transactional - public void unsubscribeFromRegistry( - @PathParam("registryId") String registryId) throws Exception { + public void unsubscribeFromRegistry(@PathParam("registryId") + String registryId) throws Exception { statusHandler.info("Disconnecting replication with [" + registryId + "]..."); RegistryType remoteRegistry = getRegistry(registryId); @@ -824,8 +786,8 @@ public class RegistryFederationManager implements IRegistryFederationManager, @GET @Path("addReplicationServer/{registryId}") @Transactional - public void addReplicationServer(@PathParam("registryId") String registryId) - throws Exception { + public void addReplicationServer(@PathParam("registryId") + String registryId) throws Exception { getRegistry(registryId); servers.addReplicationServer(registryId); saveNotificationServers(); @@ -834,8 +796,8 @@ public class RegistryFederationManager implements IRegistryFederationManager, @GET @Path("removeReplicationServer/{registryId}") @Transactional - public void removeReplicationServer( - @PathParam("registryId") String registryId) throws Exception { + public void removeReplicationServer(@PathParam("registryId") + String registryId) throws Exception { getRegistry(registryId); servers.removeReplicationServer(registryId); saveNotificationServers(); @@ -978,7 +940,8 @@ public class RegistryFederationManager implements IRegistryFederationManager, } public void processReplicationEvents() { - if (federationEnabled && DbInit.isDbInitialized() && initialized.get()) { + if (federationEnabled && DbInit.isDbInitialized() && initialized.get() + && !SYNC_IN_PROGRESS.get()) { if (!running.getAndSet(true)) { try { for (final String remoteRegistryId : servers @@ -1029,7 +992,7 @@ public class RegistryFederationManager implements IRegistryFederationManager, .getBaseURL())) { List events = replicationEventDao - .getReplicationEvents(remoteRegistryId); + .getReplicationEvents(remoteRegistryId, SYNC_BATCH_SIZE); List>> orderedBatchedEvents = new ArrayList>>(); SimpleEntry> lastEntry = null; @@ -1135,7 +1098,14 @@ public class RegistryFederationManager implements IRegistryFederationManager, @Transactional public void updateUpTime() { if (initialized.get()) { - federatedRegistryMonitor.updateTime(); + if (SYNC_NECESSARY) { + if (!SYNC_IN_PROGRESS.get() + && TimeUtil.newGmtCalendar().get(Calendar.MINUTE) % 15 == 0) { + sendSyncMessage(); + } + } else { + federatedRegistryMonitor.updateTime(); + } } } diff --git a/edexOsgi/com.raytheon.uf.edex.datadelivery.registry/src/com/raytheon/uf/edex/datadelivery/registry/web/RegistryAvailableRestService.java b/edexOsgi/com.raytheon.uf.edex.datadelivery.registry/src/com/raytheon/uf/edex/datadelivery/registry/web/RegistryAvailableRestService.java index 53fb3bff8b..d6d4d9ab46 100644 --- a/edexOsgi/com.raytheon.uf.edex.datadelivery.registry/src/com/raytheon/uf/edex/datadelivery/registry/web/RegistryAvailableRestService.java +++ b/edexOsgi/com.raytheon.uf.edex.datadelivery.registry/src/com/raytheon/uf/edex/datadelivery/registry/web/RegistryAvailableRestService.java @@ -65,11 +65,14 @@ public class RegistryAvailableRestService implements @GET @Produces("text/plain") public String isRegistryAvailable() { - if (DbInit.isDbInitialized() - && RegistryFederationManager.initialized.get()) { - return RegistryAvailability.AVAILABLE; - } else { - return RegistryAvailability.DB_NOT_INITIALIZED; + if (DbInit.isDbInitialized()) { + if (RegistryFederationManager.initialized.get()) { + if(RegistryFederationManager.SYNC_IN_PROGRESS.get()){ + return RegistryAvailability.SYNC_IN_PROGRESS; + } + return RegistryAvailability.AVAILABLE; + } } + return RegistryAvailability.DB_NOT_INITIALIZED; } } diff --git a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/res/spring/ebxml-eventbus.xml b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/res/spring/ebxml-eventbus.xml index 22d6eb897f..a4154f35be 100644 --- a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/res/spring/ebxml-eventbus.xml +++ b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/res/spring/ebxml-eventbus.xml @@ -13,4 +13,8 @@ + + + + \ No newline at end of file diff --git a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/res/spring/ebxml-impl.xml b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/res/spring/ebxml-impl.xml index b33b9ff8b1..717407dfbd 100644 --- a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/res/spring/ebxml-impl.xml +++ b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/res/spring/ebxml-impl.xml @@ -36,6 +36,7 @@ + diff --git a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/res/spring/ebxml-registry-dao.xml b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/res/spring/ebxml-registry-dao.xml index 9e734ca8ec..03cd1bb85c 100644 --- a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/res/spring/ebxml-registry-dao.xml +++ b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/res/spring/ebxml-registry-dao.xml @@ -28,7 +28,6 @@ - diff --git a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/dao/RegistryObjectDao.java b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/dao/RegistryObjectDao.java index 6c72955304..3836d3f030 100644 --- a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/dao/RegistryObjectDao.java +++ b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/dao/RegistryObjectDao.java @@ -22,7 +22,6 @@ package com.raytheon.uf.edex.registry.ebxml.dao; import java.util.List; import oasis.names.tc.ebxml.regrep.xsd.rim.v4.RegistryObjectType; -import oasis.names.tc.ebxml.regrep.xsd.rim.v4.SlotType; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; @@ -45,6 +44,7 @@ import com.raytheon.uf.edex.registry.ebxml.exception.EbxmlRegistryException; * 7/29/2013 2191 bphillip Added new methods to support registry synchronization * 8/1/2013 1693 bphillip Added methods to facilitate implementation of the lifecyclemanager according to the 4.0 spec * 2/13/2014 2769 bphillip Added read only flags to query methods + * 4/11/2014 3011 bphillip Changed merge to not delete unused slots * * * @@ -54,9 +54,6 @@ import com.raytheon.uf.edex.registry.ebxml.exception.EbxmlRegistryException; public class RegistryObjectDao extends RegistryObjectTypeDao { - /** Data access object for accessing slots */ - private SlotTypeDao slotDao; - /** Delete object type parameterized statement */ private static final String GET_IDS_BY_OBJECT_TYPE = "SELECT regObj.id FROM RegistryObjectType regObj WHERE regObj.objectType=:objectType"; @@ -85,10 +82,6 @@ public class RegistryObjectDao extends */ public void merge(RegistryObjectType newObject, RegistryObjectType existingObject) { - // Delete the existing slot to prevent orphans - for (SlotType slot : existingObject.getSlot()) { - slotDao.delete(slot); - } newObject.setId(existingObject.getId()); template.merge(newObject); } @@ -198,8 +191,4 @@ public class RegistryObjectDao extends return RegistryObjectType.class; } - public void setSlotDao(SlotTypeDao slotDao) { - this.slotDao = slotDao; - } - } diff --git a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/RegistryGarbageCollector.java b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/RegistryGarbageCollector.java index 1c800d5ecd..17cd6c76ab 100644 --- a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/RegistryGarbageCollector.java +++ b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/RegistryGarbageCollector.java @@ -27,10 +27,15 @@ import oasis.names.tc.ebxml.regrep.xsd.rim.v4.AuditableEventType; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import com.google.common.eventbus.Subscribe; import com.raytheon.uf.common.status.IUFStatusHandler; import com.raytheon.uf.common.status.UFStatus; +import com.raytheon.uf.common.time.util.TimeUtil; +import com.raytheon.uf.common.util.CollectionUtil; import com.raytheon.uf.edex.registry.ebxml.dao.AuditableEventTypeDao; +import com.raytheon.uf.edex.registry.ebxml.dao.SlotTypeDao; import com.raytheon.uf.edex.registry.ebxml.exception.EbxmlRegistryException; +import com.raytheon.uf.edex.registry.events.DeleteSlotEvent; /** * @@ -49,6 +54,7 @@ import com.raytheon.uf.edex.registry.ebxml.exception.EbxmlRegistryException; * 1/15/2014 2613 bphillip Added Hibernate flush() call * 2/4/2014 2769 bphillip Removed flush and clear call * 2/13/2014 2769 bphillip Refactored to no longer use executor threads + * 4/11/2014 3011 bphillip Added slot purging via event bus notifications * * * @author bphillip @@ -68,6 +74,8 @@ public class RegistryGarbageCollector { /** Data access object for AuditableEventType */ private AuditableEventTypeDao eventDao; + private SlotTypeDao slotDao; + /** The number of events to delete per batch */ private static final int DELETE_BATCH_SIZE = 100; @@ -85,9 +93,11 @@ public class RegistryGarbageCollector { * @param eventDao * The auditable event dao to use */ - public RegistryGarbageCollector(AuditableEventTypeDao eventDao) { + public RegistryGarbageCollector(AuditableEventTypeDao eventDao, + SlotTypeDao slotDao) { this(); this.eventDao = eventDao; + this.slotDao = slotDao; } @@ -126,4 +136,18 @@ public class RegistryGarbageCollector { } } while (!expiredEvents.isEmpty()); } + + @Subscribe + public void deleteOrphanedSlot(DeleteSlotEvent slotEvent) { + if (!CollectionUtil.isNullOrEmpty(slotEvent.getSlotsToDelete())) { + long start = TimeUtil.currentTimeMillis(); + statusHandler.info("Deleting " + + slotEvent.getSlotsToDelete().size() + " slots..."); + slotDao.deleteAll(slotEvent.getSlotsToDelete()); + statusHandler.info("Deleted " + slotEvent.getSlotsToDelete().size() + + " slots in " + (TimeUtil.currentTimeMillis() - start) + + " ms"); + } + } + } diff --git a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/lifecycle/LifecycleManagerImpl.java b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/lifecycle/LifecycleManagerImpl.java index c5fe63d687..e619ea026b 100644 --- a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/lifecycle/LifecycleManagerImpl.java +++ b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/lifecycle/LifecycleManagerImpl.java @@ -80,6 +80,7 @@ import com.raytheon.uf.edex.registry.ebxml.util.EbxmlExceptionUtil; import com.raytheon.uf.edex.registry.ebxml.util.EbxmlObjectUtil; import com.raytheon.uf.edex.registry.ebxml.util.xpath.RegistryXPathProcessor; import com.raytheon.uf.edex.registry.events.CreateAuditTrailEvent; +import com.raytheon.uf.edex.registry.events.DeleteSlotEvent; /** * The LifecycleManager interface allows a client to perform various lifecycle @@ -108,7 +109,8 @@ import com.raytheon.uf.edex.registry.events.CreateAuditTrailEvent; * Separate update from create notifications. * 12/2/2013 1829 bphillip Auditable events are not genereted via messages on the event bus * 01/21/2014 2613 bphillip Removed verbose log message from removeObjects - * 2/19/2014 2769 bphillip Added current time to audit trail events + * 2/19/2014 2769 bphillip Added current time to audit trail events + * 4/11/2014 3011 bphillip Modified merge behavior * * * @@ -417,7 +419,7 @@ public class LifecycleManagerImpl implements LifecycleManager { */ checkReplica(request, obj, existingObject); objsUpdated.add(obj); - registryObjectDao.merge(obj, existingObject); + mergeObjects(obj, existingObject); statusHandler.info("Object [" + objectId + "] replaced in the registry."); } @@ -737,7 +739,7 @@ public class LifecycleManagerImpl implements LifecycleManager { + "..."); RegistryObjectType updatedObject = applyUpdates(objToUpdate, updateActions); - registryObjectDao.merge(updatedObject, objToUpdate); + mergeObjects(updatedObject, objToUpdate); } if (!objectsToUpdate.isEmpty()) { EventBus.publish(new CreateAuditTrailEvent(request.getId(), @@ -752,6 +754,14 @@ public class LifecycleManagerImpl implements LifecycleManager { return response; } + private void mergeObjects(RegistryObjectType newObject, + RegistryObjectType existingObject) { + registryObjectDao.merge(newObject, existingObject); + DeleteSlotEvent deleteSlotEvent = new DeleteSlotEvent( + existingObject.getSlot()); + EventBus.publish(deleteSlotEvent); + } + private RegistryObjectType applyUpdates(RegistryObjectType objectToUpdate, List updateActions) throws MsgRegistryException { for (UpdateActionType updateAction : updateActions) { diff --git a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/events/DeleteSlotEvent.java b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/events/DeleteSlotEvent.java new file mode 100644 index 0000000000..11868fc1fa --- /dev/null +++ b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/events/DeleteSlotEvent.java @@ -0,0 +1,67 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.edex.registry.events; + +import java.util.List; + +import oasis.names.tc.ebxml.regrep.xsd.rim.v4.SlotType; + +import com.raytheon.uf.common.event.Event; + +/** + * Event containing slots to be deleted by the registry garbage collector + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#     Engineer    Description
+ * ------------ ----------  ----------- --------------------------
+ * 4/11/2014    3011         bphillip    Initial Coding
+ * 
+ * + * @author bphillip + * @version 1 + */ +public class DeleteSlotEvent extends Event { + + private static final long serialVersionUID = -2818002679753482984L; + + private List slotsToDelete; + + public DeleteSlotEvent(){ + super(); + } + + public DeleteSlotEvent(List slotsToDelete){ + this.slotsToDelete = slotsToDelete; + } + + public List getSlotsToDelete() { + return slotsToDelete; + } + + public void setSlotsToDelete(List slotsToDelete) { + this.slotsToDelete = slotsToDelete; + } + + + +}