001/**
002 * Copyright 2005-2017 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 */
016package org.kuali.rice.ken.service.impl;
017
018import org.kuali.rice.ken.bo.NotificationMessageDelivery;
019import org.kuali.rice.ken.deliverer.NotificationMessageDeliverer;
020import org.kuali.rice.ken.deliverer.impl.KEWActionListMessageDeliverer;
021import org.kuali.rice.ken.exception.NotificationAutoRemoveException;
022import org.kuali.rice.ken.service.NotificationMessageDeliveryAutoRemovalService;
023import org.kuali.rice.ken.service.NotificationMessageDeliveryService;
024import org.kuali.rice.ken.service.ProcessingResult;
025import org.kuali.rice.ken.util.NotificationConstants;
026import org.kuali.rice.krad.data.DataObjectService;
027import org.springframework.transaction.PlatformTransactionManager;
028
029import java.sql.Timestamp;
030import java.util.ArrayList;
031import java.util.Collection;
032import java.util.List;
033import java.util.concurrent.ExecutorService;
034
035/**
036 * Auto removes expired message deliveries.
037 * @author Kuali Rice Team (rice.collab@kuali.org)
038 */
039public class NotificationMessageDeliveryAutoRemovalServiceImpl extends ConcurrentJob<NotificationMessageDelivery> implements NotificationMessageDeliveryAutoRemovalService {
040    private DataObjectService dataObjectService;
041    private NotificationMessageDeliveryService messageDeliveryService;
042
043    /**
044     * Constructs a NotificationMessageDeliveryDispatchServiceImpl instance.
045     * @param dataObjectService service persists data to datasource
046     * @param txManager
047     * @param executor
048     * @param messageDeliveryService
049     */
050    public NotificationMessageDeliveryAutoRemovalServiceImpl(DataObjectService dataObjectService, PlatformTransactionManager txManager,
051            ExecutorService executor, NotificationMessageDeliveryService messageDeliveryService) {
052        super(txManager, executor);
053        this.messageDeliveryService = messageDeliveryService;
054        this.dataObjectService = dataObjectService;
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.setLockedDateValue(null);
114        dataObjectService.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}