001    /*
002     * Copyright 2007 The Kuali Foundation
003     * 
004     * Licensed under the Educational Community License, Version 2.0 (the "License");
005     * you may not use this file except in compliance with the License.
006     * You may obtain a copy of the License at
007     * 
008     * http://www.opensource.org/licenses/ecl2.php
009     * 
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS,
012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     * See the License for the specific language governing permissions and
014     * limitations under the License.
015     */
016    package org.kuali.rice.ken.service.impl;
017    
018    import java.sql.Timestamp;
019    import java.util.ArrayList;
020    import java.util.Collection;
021    import java.util.List;
022    import java.util.concurrent.ExecutorService;
023    
024    import org.kuali.rice.core.dao.GenericDao;
025    import org.kuali.rice.ken.bo.NotificationMessageDelivery;
026    import org.kuali.rice.ken.deliverer.NotificationMessageDeliverer;
027    import org.kuali.rice.ken.deliverer.impl.KEWActionListMessageDeliverer;
028    import org.kuali.rice.ken.exception.NotificationAutoRemoveException;
029    import org.kuali.rice.ken.service.NotificationMessageDeliveryAutoRemovalService;
030    import org.kuali.rice.ken.service.NotificationMessageDeliveryService;
031    import org.kuali.rice.ken.service.ProcessingResult;
032    import org.kuali.rice.ken.util.NotificationConstants;
033    import org.springframework.transaction.PlatformTransactionManager;
034    
035    /**
036     * Auto removes expired message deliveries.
037     * @author Kuali Rice Team (rice.collab@kuali.org)
038     */
039    public class NotificationMessageDeliveryAutoRemovalServiceImpl extends ConcurrentJob<NotificationMessageDelivery> implements NotificationMessageDeliveryAutoRemovalService {
040        private GenericDao businessObjectDao;
041        private NotificationMessageDeliveryService messageDeliveryService;
042    
043        /**
044         * Constructs a NotificationMessageDeliveryDispatchServiceImpl instance.
045         * @param businessObjectDao
046         * @param txManager
047         * @param executor
048         * @param messageDeliveryRegistryService
049         */
050        public NotificationMessageDeliveryAutoRemovalServiceImpl(GenericDao businessObjectDao, PlatformTransactionManager txManager, 
051                ExecutorService executor, NotificationMessageDeliveryService messageDeliveryService) {
052            super(txManager, executor);
053            this.messageDeliveryService = messageDeliveryService;
054            this.businessObjectDao = businessObjectDao;
055        }
056    
057        /**
058         * @see org.kuali.rice.ken.service.impl.ConcurrentJob#takeAvailableWorkItems()
059         */
060        @Override
061        protected Collection<NotificationMessageDelivery> takeAvailableWorkItems() {
062            return messageDeliveryService.takeMessageDeliveriesForAutoRemoval();
063        }
064    
065        /**
066         * @see org.kuali.rice.ken.service.impl.ConcurrentJob#processWorkItem(java.lang.Object)
067         */
068        @Override
069        protected Collection<String> processWorkItems(Collection<NotificationMessageDelivery> messageDeliveries) {
070            NotificationMessageDelivery firstMessageDelivery = messageDeliveries.iterator().next();
071    
072            KEWActionListMessageDeliverer deliverer = new KEWActionListMessageDeliverer();
073            Collection<String> successes = new ArrayList<String>();
074            for (NotificationMessageDelivery delivery: messageDeliveries) {
075                successes.addAll(autoRemove(deliverer, delivery));
076            }
077            return successes;
078        }
079    
080        /**
081         * Auto-removes a single message delivery
082         * @param messageDeliverer the message deliverer
083         * @param messageDelivery the message delivery to auto-remove
084         * @return collection of strings indicating successful auto-removals
085         */
086        protected Collection<String> autoRemove(NotificationMessageDeliverer messageDeliverer, NotificationMessageDelivery messageDelivery) {
087            List<String> successes = new ArrayList<String>(1);
088    
089            // we have our message deliverer, so tell it to auto remove the message
090            try {
091                messageDeliverer.autoRemoveMessageDelivery(messageDelivery);
092                LOG.debug("Auto-removal of message delivery '" + messageDelivery.getId() + "' for notification '" + messageDelivery.getNotification().getId() + "' was successful.");
093                successes.add("Auto-removal of message delivery '" + messageDelivery.getId() + "' for notification '" + messageDelivery.getNotification().getId() + "' was successful.");
094            } catch (NotificationAutoRemoveException nmde) {
095                LOG.error("Error auto-removing message " + messageDelivery);
096                throw new RuntimeException(nmde);
097            }
098            
099            // unlock item
100            // now update the status of the delivery message instance to AUTO_REMOVED and persist
101            markAutoRemoved(messageDelivery);
102    
103            return successes;
104        }
105    
106        /**
107         * Marks a MessageDelivery as having been auto-removed, and unlocks it
108         * @param messageDelivery the messageDelivery instance to mark
109         */
110        protected void markAutoRemoved(NotificationMessageDelivery messageDelivery) {
111            messageDelivery.setMessageDeliveryStatus(NotificationConstants.MESSAGE_DELIVERY_STATUS.AUTO_REMOVED);
112            // mark as unlocked
113            messageDelivery.setLockedDate(null);
114            businessObjectDao.save(messageDelivery);
115        }
116    
117        /**
118         * @see org.kuali.rice.ken.service.impl.ConcurrentJob#unlockWorkItem(java.lang.Object)
119         */
120        @Override
121        protected void unlockWorkItem(NotificationMessageDelivery delivery) {
122            messageDeliveryService.unlockMessageDelivery(delivery);
123        }
124    
125        /**
126         * This implementation looks up all UNDELIVERED/DELIVERED message deliveries with an autoRemoveDateTime <= current date time and then iterates 
127         * over each to call the appropriate functions to do the "auto-removal" by "canceling" each associated notification 
128         * workflow document.
129         * @see org.kuali.rice.ken.service.NotificationMessageDeliveryDispatchService#processAutoRemovalOfDeliveredNotificationMessageDeliveries()
130         */
131        public ProcessingResult processAutoRemovalOfDeliveredNotificationMessageDeliveries() {
132            LOG.debug("[" + new Timestamp(System.currentTimeMillis()).toString() + "] STARTING NOTIFICATION AUTO-REMOVAL PROCESSING");
133    
134            ProcessingResult result = run();
135            
136            LOG.debug("[" + new Timestamp(System.currentTimeMillis()).toString() + "] FINISHED NOTIFICATION AUTO-REMOVAL PROCESSING - Successes = " + result.getSuccesses().size() + ", Failures = " + result.getFailures().size());
137    
138            return result;
139        }
140    }