From 4a174edcbb5fa6c4ae57e7f4c27f1880b6b25377 Mon Sep 17 00:00:00 2001 From: Benjamin Phillippe Date: Wed, 11 Sep 2013 15:49:08 -0500 Subject: [PATCH] Issue #2354 Fixed replication of deleted objects Change-Id: Ibe9d3ca094d90fdef7ecf2a317f362f2d2ba90a9 Former-commit-id: 7296b3071f4e2e426094a7040fda337c4f90860d [formerly 8a7d76cb892102a2d7f972bca128e9186f442fd7] Former-commit-id: 469710c1bbb2ba88f6034a536d5ab9618de2c46c --- .../ebxml/dao/AuditableEventTypeDao.java | 60 ++++++---- .../ebxml/services/AuditableEventService.java | 113 +++++++----------- .../lifecycle/LifecycleManagerImpl.java | 10 +- .../NotificationListenerImpl.java | 105 +++++----------- .../RegistryNotificationManager.java | 6 +- .../RegistrySubscriptionManager.java | 9 +- 6 files changed, 129 insertions(+), 174 deletions(-) diff --git a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/dao/AuditableEventTypeDao.java b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/dao/AuditableEventTypeDao.java index 1d24bf0891..579afc239b 100644 --- a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/dao/AuditableEventTypeDao.java +++ b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/dao/AuditableEventTypeDao.java @@ -21,8 +21,8 @@ package com.raytheon.uf.edex.registry.ebxml.dao; import java.math.BigInteger; +import java.util.ArrayList; import java.util.Calendar; -import java.util.Collections; import java.util.List; import javax.xml.datatype.XMLGregorianCalendar; @@ -35,6 +35,7 @@ import org.springframework.transaction.annotation.Transactional; import com.raytheon.uf.common.registry.constants.ActionTypes; import com.raytheon.uf.common.time.util.TimeUtil; +import com.raytheon.uf.common.util.CollectionUtil; import com.raytheon.uf.edex.registry.ebxml.exception.EbxmlRegistryException; import com.raytheon.uf.edex.registry.ebxml.util.EbxmlObjectUtil; @@ -53,6 +54,7 @@ import com.raytheon.uf.edex.registry.ebxml.util.EbxmlObjectUtil; * May 02, 2013 1910 djohnson Broke out registry subscription notification to a service class. * 7/29/2013 2191 bphillip Changed method to get expired events * 8/1/2013 1693 bphillip Moved creation of auditable events to the auditable event service class + * 9/11/2013 2354 bphillip Modified queries to find deleted objects * * * @@ -68,11 +70,20 @@ public class AuditableEventTypeDao extends * Query to find events of interest when sending registry replication * notifications */ - private static final String EVENTS_OF_INTEREST_QUERY = "select event from AuditableEventType as event " + private static final String FIND_EVENTS_OF_INTEREST_QUERY = "select event from AuditableEventType as event " + "left outer join event.action as action " + "left outer join action.affectedObjects as AffectedObjects " + + "left outer join action.affectedObjectRefs as AffectedObjectRefs " + "left outer join AffectedObjects.registryObject as RegistryObjects " - + "where (RegistryObjects.id in (:ids) OR action.eventType = :eventType) and event.timestamp >= :startTime"; + + "left outer join AffectedObjectRefs.objectRef as ObjRefs " + + "where (ObjRefs.id in (:ids) OR RegistryObjects.id in (:ids) OR action.eventType = :eventType) and event.timestamp >= :startTime"; + + /** + * Query to find deleted events + */ + private static final String FIND_DELETED_EVENTS_OF_INTEREST_QUERY = "select event from AuditableEventType as event " + + "left outer join event.action as action " + + "where action.eventType = :eventType and event.timestamp >= :startTime"; /** Optional end time clause */ private static final String END_TIME_CLAUSE = " and event.timestamp <= :endTime"; @@ -136,24 +147,33 @@ public class AuditableEventTypeDao extends public List getEventsOfInterest( XMLGregorianCalendar startTime, XMLGregorianCalendar endTime, List objectsOfInterest) { - if (objectsOfInterest.isEmpty()) { - return Collections.emptyList(); - } - StringBuilder buf = new StringBuilder(); - for (ObjectRefType objOfInterest : objectsOfInterest) { - buf.append(", '").append(objOfInterest.getId()).append("'"); - } - String inString = buf.toString().replaceFirst(",", ""); - if (endTime == null) { - return this.query((EVENTS_OF_INTEREST_QUERY + ORDER_CLAUSE) - .replace(IDS, inString), "startTime", startTime, - "eventType", ActionTypes.delete); - } else { - return this.query( - (EVENTS_OF_INTEREST_QUERY + END_TIME_CLAUSE + ORDER_CLAUSE) - .replace(IDS, inString), "startTime", startTime, - "eventType", ActionTypes.delete, "endTime", endTime); + String query = FIND_DELETED_EVENTS_OF_INTEREST_QUERY; + List queryParams = new ArrayList(4); + queryParams.add("eventType"); + queryParams.add(ActionTypes.delete); + queryParams.add("startTime"); + queryParams.add(startTime); + if (!CollectionUtil.isNullOrEmpty(objectsOfInterest)) { + StringBuilder buf = new StringBuilder(); + for (int i = 0; i < objectsOfInterest.size(); i++) { + if (i > 0) { + buf.append(", "); + } + buf.append("'").append(objectsOfInterest.get(i).getId()) + .append("'"); + } + query = FIND_EVENTS_OF_INTEREST_QUERY.replaceAll(IDS, buf.toString()); + + if (endTime == null) { + query += ORDER_CLAUSE; + } else { + query += END_TIME_CLAUSE + ORDER_CLAUSE; + queryParams.add("endTime"); + queryParams.add(endTime); + } } + return this.query(query, + queryParams.toArray(new Object[queryParams.size()])); } /** diff --git a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/AuditableEventService.java b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/AuditableEventService.java index 403a8130fe..8e35a1ddcd 100644 --- a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/AuditableEventService.java +++ b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/AuditableEventService.java @@ -25,12 +25,10 @@ import oasis.names.tc.ebxml.regrep.xsd.rim.v4.ActionType; import oasis.names.tc.ebxml.regrep.xsd.rim.v4.AuditableEventType; import oasis.names.tc.ebxml.regrep.xsd.rim.v4.ObjectRefListType; import oasis.names.tc.ebxml.regrep.xsd.rim.v4.ObjectRefType; -import oasis.names.tc.ebxml.regrep.xsd.rim.v4.RegistryObjectListType; import oasis.names.tc.ebxml.regrep.xsd.rim.v4.RegistryObjectType; import oasis.names.tc.ebxml.regrep.xsd.rim.v4.VersionInfoType; import oasis.names.tc.ebxml.regrep.xsd.rs.v4.RegistryRequestType; -import com.raytheon.uf.common.registry.constants.ActionTypes; import com.raytheon.uf.common.registry.constants.RegistryObjectTypes; import com.raytheon.uf.common.registry.constants.StatusTypes; import com.raytheon.uf.common.registry.ebxml.RegistryUtil; @@ -53,6 +51,7 @@ import com.raytheon.uf.edex.registry.ebxml.util.EbxmlObjectUtil; * ------------ ---------- ----------- -------------------------- * May 02, 2013 1910 djohnson Extracted subscription notification from the dao. * 8/1/2013 1692 bphillip Refactored auditable event creation + * 9/11/2013 2254 bphillip Cleaned up creation of auditable events * * * @@ -90,36 +89,24 @@ public class AuditableEventService { * Creates auditable events from the given objects * * @param request - * The request object which was process that generated the events - * @param objectsCreated - * The objects created during the processing of the request - * @param objectsUpdated - * The objects updated during the processing of the request - * @param objectsVersioned - * The objects versioned during the processing of the request - * @param objectsRemoved - * The objects removed during the processing of the request + * The request that generated the changes + * @param actionType + * The action that was taken on the object + * @param objectsAffected + * The objects that were affected * @throws EbxmlRegistryException - * If errors occur creating the event + * If errors occur while creating the event */ public void createAuditableEventFromObjects(RegistryRequestType request, - List objectsCreated, - List objectsUpdated, - List objectsVersioned, - List objectsRemoved) + String actionType, List objectsAffected) throws EbxmlRegistryException { - AuditableEventType event = createEvent(request, - TimeUtil.currentTimeMillis()); - addRegistryObjectActionToEvent(event, ActionTypes.create, - objectsCreated); - addRegistryObjectActionToEvent(event, ActionTypes.update, - objectsUpdated); - addRegistryObjectActionToEvent(event, ActionTypes.version, - objectsVersioned); - addRegistryObjectActionToEvent(event, ActionTypes.delete, - objectsRemoved); - auditDao.create(event); - notifySubscriptionManager(); + if (!CollectionUtil.isNullOrEmpty(objectsAffected)) { + AuditableEventType event = createEvent(request, + TimeUtil.currentTimeMillis()); + addRegistryObjectActionToEvent(event, actionType, objectsAffected); + auditDao.create(event); + notifySubscriptionManager(); + } } /** @@ -134,49 +121,39 @@ public class AuditableEventService { */ private void addRegistryObjectActionToEvent(AuditableEventType event, String eventType, List objs) { - if (!CollectionUtil.isNullOrEmpty(objs)) { - ActionType action = new ActionType(); - action.setEventType(eventType); - RegistryObjectListType objList = new RegistryObjectListType(); - objList.getRegistryObject().addAll(objs); - action.setAffectedObjects(objList); - event.getAction().add(action); + ActionType action = new ActionType(); + action.setEventType(eventType); + ObjectRefListType objList = new ObjectRefListType(); + for (RegistryObjectType obj : objs) { + objList.getObjectRef().add(new ObjectRefType(obj.getId())); } + action.setAffectedObjectRefs(objList); + event.getAction().add(action); + } /** * Creates an auditable event from the given object references * * @param request - * The request that is generating the event - * @param objectsCreated - * References to the objects created during the processing of the - * request - * @param objectsUpdated - * References to the objects updated during the processing of the - * request - * @param objectsVersioned - * References to the object versioned during the processing of - * the request - * @param objectsRemoved - * References to the objects removed during the processing of the - * request + * The request that generated the changes + * @param actionType + * The action that was taken on the object + * @param objectsAffected + * The references to the objects that were affected * @throws EbxmlRegistryException - * If error occur while creating the event + * If errors occur while creating the event */ public void createAuditableEventFromRefs(RegistryRequestType request, - List objectsCreated, - List objectsUpdated, - List objectsVersioned, - List objectsRemoved) throws EbxmlRegistryException { - AuditableEventType event = createEvent(request, - TimeUtil.currentTimeMillis()); - addObjectRefActionToEvent(event, ActionTypes.create, objectsCreated); - addObjectRefActionToEvent(event, ActionTypes.update, objectsUpdated); - addObjectRefActionToEvent(event, ActionTypes.version, objectsVersioned); - addObjectRefActionToEvent(event, ActionTypes.delete, objectsRemoved); - auditDao.create(event); - notifySubscriptionManager(); + String actionType, List objectsAffected) + throws EbxmlRegistryException { + if (!CollectionUtil.isNullOrEmpty(objectsAffected)) { + AuditableEventType event = createEvent(request, + TimeUtil.currentTimeMillis()); + addObjectRefActionToEvent(event, actionType, objectsAffected); + auditDao.create(event); + notifySubscriptionManager(); + } } /** @@ -191,14 +168,12 @@ public class AuditableEventService { */ private void addObjectRefActionToEvent(AuditableEventType event, String eventType, List objs) { - if (!CollectionUtil.isNullOrEmpty(objs)) { - ActionType action = new ActionType(); - action.setEventType(eventType); - ObjectRefListType objList = new ObjectRefListType(); - objList.getObjectRef().addAll(objs); - action.setAffectedObjectRefs(objList); - event.getAction().add(action); - } + ActionType action = new ActionType(); + action.setEventType(eventType); + ObjectRefListType objList = new ObjectRefListType(); + objList.getObjectRef().addAll(objs); + action.setAffectedObjectRefs(objList); + event.getAction().add(action); } /** 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 ef86ce246d..95ae234c12 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 @@ -52,6 +52,7 @@ import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; import com.raytheon.uf.common.event.EventBus; +import com.raytheon.uf.common.registry.constants.ActionTypes; import com.raytheon.uf.common.registry.constants.AssociationTypes; import com.raytheon.uf.common.registry.constants.DeletionScope; import com.raytheon.uf.common.registry.constants.QueryLanguages; @@ -99,6 +100,7 @@ import com.raytheon.uf.edex.registry.ebxml.util.xpath.RegistryXPathProcessor; * Apr 24, 2013 1910 djohnson Use validation framework to check references. * Jun 24, 2013 2106 djohnson Requires a transaction to already be open. * 8/1/2013 1693 bphillip Added check references and refactored submit objects to conform to EBXML 4.0 spec + * 9/11/2013 2254 bphillip Cleaned up creation of auditable events * * * @@ -270,7 +272,7 @@ public class LifecycleManagerImpl implements LifecycleManager { + "]"); } auditableEventService.createAuditableEventFromObjects(request, - null, null, null, objectsToRemove); + ActionTypes.delete, objectsToRemove); } catch (EbxmlRegistryException e) { throw EbxmlExceptionUtil.createMsgRegistryException( REMOVE_OBJECTS_ERROR_MSG, e); @@ -457,7 +459,9 @@ public class LifecycleManagerImpl implements LifecycleManager { statusHandler.info("Creating auditable events...."); try { auditableEventService.createAuditableEventFromObjects(request, - objsCreated, objsUpdated, null, null); + ActionTypes.create, objsCreated); + auditableEventService.createAuditableEventFromObjects(request, + ActionTypes.update, objsUpdated); } catch (EbxmlRegistryException e) { throw EbxmlExceptionUtil.createMsgRegistryException( SUBMIT_OBJECTS_ERROR_MSG, e); @@ -737,7 +741,7 @@ public class LifecycleManagerImpl implements LifecycleManager { } try { auditableEventService.createAuditableEventFromObjects(request, - null, objectsToUpdate, null, null); + ActionTypes.update, objectsToUpdate); } catch (EbxmlRegistryException e) { throw EbxmlExceptionUtil.createMsgRegistryException( UPDATE_OBJECTS_ERROR_MSG, e); diff --git a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/notification/NotificationListenerImpl.java b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/notification/NotificationListenerImpl.java index 2a5fd37b0a..2944c00065 100644 --- a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/notification/NotificationListenerImpl.java +++ b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/notification/NotificationListenerImpl.java @@ -78,6 +78,7 @@ import com.raytheon.uf.edex.registry.ebxml.util.EbxmlObjectUtil; * 3/18/2013 1082 bphillip Initial creation * 4/9/2013 1802 bphillip Implemented notification handling * 5/21/2013 2022 bphillip Reworked how notifications are handled + * 9/11/2013 2254 bphillip Cleaned up handling of notifications and removed unneccessary code * * * @@ -129,11 +130,12 @@ public class NotificationListenerImpl implements NotificationListener { // Process the received auditable events and add them to the appropriate // list based on the action performed - RegistryObjectActionList objActionList = new RegistryObjectActionList(); + for (AuditableEventType event : events) { List actions = event.getAction(); for (ActionType action : actions) { String eventType = action.getEventType(); + List objectIds = new ArrayList(); // Verify this is a valid event type if (!classificationNodeDao.isValidNode(eventType)) { @@ -145,58 +147,56 @@ public class NotificationListenerImpl implements NotificationListener { if (action.getAffectedObjectRefs() != null) { for (ObjectRefType ref : action.getAffectedObjectRefs() .getObjectRef()) { - objActionList.addAction(eventType, ref.getId()); + objectIds.add(ref.getId()); } } else if (action.getAffectedObjects() != null) { for (RegistryObjectType regObj : action .getAffectedObjects().getRegistryObject()) { - objActionList.addAction(eventType, regObj.getId()); + objectIds.add(regObj.getId()); } } else { statusHandler.info("Event " + event.getId() + " contains 0 affected objects "); + continue; } - } - } - for (RegistryObjectAction regObjAction : objActionList.getActionList()) { - String action = regObjAction.getAction(); - try { - if (action.equals(ActionTypes.create) - || action.equals(ActionTypes.update)) { - SubmitObjectsRequest submitRequest = createSubmitObjectsRequest( - clientBaseURL, notification.getId(), - regObjAction.getObjIds(), Mode.CREATE_OR_REPLACE); - lcm.submitObjects(submitRequest); - } else if (action.equals(ActionTypes.delete)) { + if (eventType.equals(ActionTypes.create) + || eventType.equals(ActionTypes.update)) { + try { + SubmitObjectsRequest submitRequest = createSubmitObjectsRequest( + clientBaseURL, notification.getId(), objectIds, + Mode.CREATE_OR_REPLACE); + lcm.submitObjects(submitRequest); + } catch (MsgRegistryException e) { + statusHandler.error( + "Error creating objects in registry!", e); + } catch (EbxmlRegistryException e) { + statusHandler.error( + "Error creating submit objects request!", e); + } + } else if (eventType.equals(ActionTypes.delete)) { ObjectRefListType refList = new ObjectRefListType(); - for (String id : regObjAction.getObjIds()) { + for (String id : objectIds) { RegistryObjectType object = registryObjectDao .getById(id); if (object != null) { - String replicaHome = object - .getSlotValue(EbxmlObjectUtil.HOME_SLOT_NAME); - if (clientBaseURL.equals(replicaHome)) { - ObjectRefType ref = new ObjectRefType(); - ref.setId(id); - refList.getObjectRef().add(ref); - } + refList.getObjectRef().add(new ObjectRefType(id)); } } RemoveObjectsRequest request = new RemoveObjectsRequest( "Remove Objects for notification [" + notification.getId() + "]", "Notification delete object submission", null, - null, refList, false, false, + null, refList, false, true, DeletionScope.DELETE_ALL); - lcm.removeObjects(request); + try { + lcm.removeObjects(request); + } catch (MsgRegistryException e) { + statusHandler.error( + "Error creating remove objects request!", e); + } } - } catch (EbxmlRegistryException e) { - statusHandler - .error("Error getting remote objects to create", e); - } catch (MsgRegistryException e) { - statusHandler.error("Error creating objects in registry!", e); } } @@ -321,49 +321,4 @@ public class NotificationListenerImpl implements NotificationListener { this.registryDao = registryDao; } - private class RegistryObjectActionList { - - List actionList = new ArrayList(); - - public void addAction(String action, String objId) { - if (actionList.isEmpty() - || !actionList.get(actionList.size() - 1).getAction() - .equals(action)) { - RegistryObjectAction newAction = new RegistryObjectAction( - action); - newAction.addObj(objId); - actionList.add(newAction); - } else { - actionList.get(actionList.size() - 1).addObj(objId); - } - } - - public List getActionList() { - return actionList; - } - } - - private class RegistryObjectAction { - - private String action; - - private List objIds = new ArrayList(); - - public RegistryObjectAction(String action) { - this.action = action; - } - - public void addObj(String obj) { - this.objIds.add(obj); - } - - public String getAction() { - return action; - } - - public List getObjIds() { - return objIds; - } - } - } diff --git a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/notification/RegistryNotificationManager.java b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/notification/RegistryNotificationManager.java index f891c43ae5..81325b7a66 100644 --- a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/notification/RegistryNotificationManager.java +++ b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/notification/RegistryNotificationManager.java @@ -39,6 +39,7 @@ import oasis.names.tc.ebxml.regrep.xsd.rim.v4.SubscriptionType; import org.springframework.transaction.annotation.Transactional; import com.raytheon.uf.common.dataplugin.persist.IPersistableDataObject; +import com.raytheon.uf.common.registry.constants.ActionTypes; import com.raytheon.uf.common.registry.constants.RegistryObjectTypes; import com.raytheon.uf.common.registry.constants.StatusTypes; import com.raytheon.uf.common.registry.ebxml.RegistryUtil; @@ -65,6 +66,7 @@ import com.raytheon.uf.edex.registry.ebxml.util.EbxmlObjectUtil; * 4/15/2013 1905 bphillip Implemented notification to email endpoints * Apr 17, 2013 1672 djohnson No longer cares about notification protocol. * 5/21/2013 2022 bphillip Cleaned up unused method parameters and batching of notifications + * 9/11/2013 2354 bphillip Added logic to ensure delete events get included in notifications * * * @author bphillip @@ -229,7 +231,7 @@ public class RegistryNotificationManager { .getAffectedObjectRefs().getObjectRef(); for (ObjectRefType obj : objRefs) { boolean found = objectInList(objectsOfInterest, obj); - if (!found) { + if (!found && !action.equals(ActionTypes.delete)) { refsToRemove.add(obj); } } @@ -239,7 +241,7 @@ public class RegistryNotificationManager { .getAffectedObjects().getRegistryObject(); for (RegistryObjectType obj : regObjs) { boolean found = objectInList(objectsOfInterest, obj); - if (!found) { + if (!found && !action.equals(ActionTypes.delete)) { objectsToRemove.add(obj); } } diff --git a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/notification/RegistrySubscriptionManager.java b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/notification/RegistrySubscriptionManager.java index 275ccd67f8..9769d85a0e 100644 --- a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/notification/RegistrySubscriptionManager.java +++ b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/services/notification/RegistrySubscriptionManager.java @@ -91,6 +91,7 @@ import com.raytheon.uf.edex.registry.ebxml.util.EbxmlObjectUtil; * event. * 6/4/2013 2022 bphillip Changed slot type of subscription last run time. Longs were being truncated when casting to ints * 9/5/2013 1538 bphillip Changed processing of each subscription to be in their own transaction. Subscriptions are now loaded on startup + * 9/11/2013 2354 bphillip Added handling of deleted objects * * * @author bphillip @@ -457,11 +458,9 @@ public class RegistrySubscriptionManager implements } statusHandler.info("Processing subscription [" + subscriptionName + "]..."); - List objectsOfInterest = getObjectsOfInterest(subscription); - if (!objectsOfInterest.isEmpty()) { - notificationManager.sendNotifications( - listeners.get(subscriptionName), objectsOfInterest); - } + notificationManager.sendNotifications( + listeners.get(subscriptionName), + getObjectsOfInterest(subscription)); updateLastRunTime(subscription, TimeUtil.currentTimeMillis()); } catch (Throwable e) { statusHandler.error(