001/** 002 * Copyright 2005-2014 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.core.api.criteria.QueryByCriteria; 019import org.kuali.rice.ken.bo.NotificationBo; 020import org.kuali.rice.ken.bo.NotificationMessageDelivery; 021import org.kuali.rice.ken.dao.NotificationMessegeDeliveryDao; 022import org.kuali.rice.ken.service.NotificationMessageDeliveryService; 023import org.kuali.rice.ken.util.NotificationConstants; 024import org.kuali.rice.krad.data.DataObjectService; 025 026import java.sql.Timestamp; 027import java.util.ArrayList; 028import java.util.Collection; 029import java.util.List; 030 031import static org.kuali.rice.core.api.criteria.PredicateFactory.*; 032 033/** 034 * NotificationService implementation - this is the default out-of-the-box implementation of the service that uses the 035 * businessObjectDao to get at the data via our OOTB DBMS. 036 * @author Kuali Rice Team (rice.collab@kuali.org) 037 */ 038public class NotificationMessageDeliveryServiceImpl implements NotificationMessageDeliveryService { 039 private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger 040 .getLogger(NotificationMessageDeliveryServiceImpl.class); 041 042 private DataObjectService dataObjectService; 043 private NotificationMessegeDeliveryDao ntdDao; 044 045 /** 046 * Constructs a NotificationServiceImpl class instance. 047 * @param dataObjectService 048 * @param ntdDao 049 */ 050 public NotificationMessageDeliveryServiceImpl(DataObjectService dataObjectService, NotificationMessegeDeliveryDao ntdDao) { 051 this.dataObjectService = dataObjectService; 052 this.ntdDao = ntdDao; 053 } 054 055 /** 056 * This is the default implementation that uses the businessObjectDao. 057 * @param id 058 * @return NotificationMessageDelivery 059 */ 060 public NotificationMessageDelivery getNotificationMessageDelivery(Long id) { 061 062 return dataObjectService.find(NotificationMessageDelivery.class, id); 063 } 064 065 /** 066 * @see org.kuali.rice.ken.service.NotificationMessageDeliveryService#getNotificationMessageDeliveryByDelivererId(java.lang.String) 067 */ 068 //switch to JPA criteria 069 @Override 070 public NotificationMessageDelivery getNotificationMessageDeliveryByDelivererId(String id) { 071 QueryByCriteria.Builder criteria = QueryByCriteria.Builder.create(); 072 criteria.setPredicates(equal(NotificationConstants.BO_PROPERTY_NAMES.DELIVERY_SYSTEM_ID, id)); 073 Collection<NotificationMessageDelivery> results = dataObjectService.findMatching(NotificationMessageDelivery.class, criteria.build()).getResults(); 074 075 if (results.isEmpty()) { 076 return null; 077 } 078 if (results.size() > 1) { 079 throw new RuntimeException("More than one message delivery found with the following delivery system id: " + id); 080 } 081 082 return results.iterator().next(); 083 } 084 085 /** 086 * @see org.kuali.rice.ken.service.NotificationMessageDeliveryService#getNotificationMessageDeliveries() 087 */ 088 public Collection<NotificationMessageDelivery> getNotificationMessageDeliveries() { 089 return dataObjectService.findMatching(NotificationMessageDelivery.class, QueryByCriteria.Builder.create().build()).getResults(); 090 } 091 092 /** 093 * @see org.kuali.rice.ken.service.NotificationMessageDeliveryService#getNotificationMessageDeliveries(java.lang.Long, java.lang.String) 094 */ 095 //switch to JPA criteria 096 @Override 097 public Collection<NotificationMessageDelivery> getNotificationMessageDeliveries(NotificationBo notification, String userRecipientId) { 098 099 QueryByCriteria.Builder criteria = QueryByCriteria.Builder.create(); 100 criteria.setPredicates(equal(NotificationConstants.BO_PROPERTY_NAMES.NOTIFICATION + ".id", notification.getId()), 101 equal(NotificationConstants.BO_PROPERTY_NAMES.USER_RECIPIENT_ID, userRecipientId)); 102 103 return dataObjectService.findMatching(NotificationMessageDelivery.class, criteria.build()).getResults(); 104 } 105 106 /** 107 * This method is responsible for atomically finding all untaken, undelivered messagedeliveries, marking them as taken 108 * and returning them to the caller for processing. 109 * NOTE: it is important that this method execute in a SEPARATE dedicated transaction; either the caller should 110 * NOT be wrapped by Spring declarative transaction and this service should be wrapped (which is the case), or 111 * the caller should arrange to invoke this from within a newly created transaction). 112 113 * @return a list of available message deliveries that have been marked as taken by the caller 114 */ 115 //switch to JPA criteria 116 @Override 117 public Collection<NotificationMessageDelivery> takeMessageDeliveriesForDispatch() { 118 // DO WITHIN TRANSACTION: get all untaken messagedeliveries, and mark as "taken" so no other thread/job takes them 119 // need to think about durability of work list 120 121 // get all undelivered message deliveries 122 Collection<NotificationMessageDelivery> messageDeliveries = ntdDao.getUndeliveredMessageDelivers(dataObjectService); 123 List<NotificationMessageDelivery> savedMsgDel = new ArrayList<NotificationMessageDelivery>(); 124 125 LOG.debug("Retrieved " + messageDeliveries.size() + " available message deliveries: " + System.currentTimeMillis()); 126 127 // mark messageDeliveries as taken 128 for (NotificationMessageDelivery delivery: messageDeliveries) { 129 delivery.setLockedDateValue(new Timestamp(System.currentTimeMillis())); 130 savedMsgDel.add(dataObjectService.save(delivery)); 131 } 132 return savedMsgDel; 133 } 134 135 /** 136 * This method is responsible for atomically finding all untaken message deliveries that are ready to be autoremoved, 137 * marking them as taken and returning them to the caller for processing. 138 * NOTE: it is important that this method execute in a SEPARATE dedicated transaction; either the caller should 139 * NOT be wrapped by Spring declarative transaction and this service should be wrapped (which is the case), or 140 * the caller should arrange to invoke this from within a newly created transaction). 141 * @return a list of notifications to be autoremoved that have been marked as taken by the caller 142 */ 143 @Override 144 public Collection<NotificationMessageDelivery> takeMessageDeliveriesForAutoRemoval() { 145 // get all UNDELIVERED/DELIVERED notification notification message delivery records with associated notifications that have and autoRemovalDateTime <= current 146 Collection<NotificationMessageDelivery> messageDeliveries = ntdDao.getMessageDeliveriesForAutoRemoval(new Timestamp(System.currentTimeMillis()), dataObjectService); 147 List<NotificationMessageDelivery> savedMsgDel = new ArrayList<NotificationMessageDelivery>(); 148 for (NotificationMessageDelivery d: messageDeliveries) { 149 d.setLockedDateValue(new Timestamp(System.currentTimeMillis())); 150 savedMsgDel.add(dataObjectService.save(d)); 151 } 152 153 return savedMsgDel; 154 155 } 156 157 /** 158 * Unlocks the specified messageDelivery object 159 * @param messageDelivery the message delivery to unlock 160 */ 161 @Override 162 public void unlockMessageDelivery(NotificationMessageDelivery messageDelivery) { 163 164 NotificationMessageDelivery d = dataObjectService.find(NotificationMessageDelivery.class, messageDelivery.getId()); 165 166 if (d == null) { 167 throw new RuntimeException("NotificationMessageDelivery #" + messageDelivery.getId() + " not found to unlock"); 168 } 169 170 d.setLockedDateValue(null); 171 dataObjectService.save(d); 172 } 173}