View Javadoc
1   /**
2    * Copyright 2005-2014 The Kuali Foundation
3    *
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.opensource.org/licenses/ecl2.php
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.kuali.rice.ken.service.impl;
17  
18  import org.kuali.rice.core.api.criteria.QueryByCriteria;
19  import org.kuali.rice.ken.bo.NotificationBo;
20  import org.kuali.rice.ken.bo.NotificationMessageDelivery;
21  import org.kuali.rice.ken.dao.NotificationMessegeDeliveryDao;
22  import org.kuali.rice.ken.service.NotificationMessageDeliveryService;
23  import org.kuali.rice.ken.util.NotificationConstants;
24  import org.kuali.rice.krad.data.DataObjectService;
25  
26  import java.sql.Timestamp;
27  import java.util.ArrayList;
28  import java.util.Collection;
29  import java.util.List;
30  
31  import static org.kuali.rice.core.api.criteria.PredicateFactory.*;
32  
33  /**
34   * NotificationService implementation - this is the default out-of-the-box implementation of the service that uses the 
35   * businessObjectDao to get at the data via our OOTB DBMS.
36   * @author Kuali Rice Team (rice.collab@kuali.org)
37   */
38  public class NotificationMessageDeliveryServiceImpl implements NotificationMessageDeliveryService {
39      private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger
40  	.getLogger(NotificationMessageDeliveryServiceImpl.class);
41  
42      private DataObjectService dataObjectService;
43      private NotificationMessegeDeliveryDao ntdDao;
44      
45      /**
46       * Constructs a NotificationServiceImpl class instance.
47       * @param dataObjectService
48       * @param ntdDao
49       */
50      public NotificationMessageDeliveryServiceImpl(DataObjectService dataObjectService, NotificationMessegeDeliveryDao ntdDao) {
51          this.dataObjectService = dataObjectService;
52          this.ntdDao = ntdDao;
53      }
54  
55      /**
56       * This is the default implementation that uses the businessObjectDao.
57       * @param id
58       * @return NotificationMessageDelivery
59       */
60      public NotificationMessageDelivery getNotificationMessageDelivery(Long id) {
61  
62          return dataObjectService.find(NotificationMessageDelivery.class, id);
63      }
64  
65      /**
66       * @see org.kuali.rice.ken.service.NotificationMessageDeliveryService#getNotificationMessageDeliveryByDelivererId(java.lang.String)
67       */
68      //switch to JPA criteria
69      @Override
70      public NotificationMessageDelivery getNotificationMessageDeliveryByDelivererId(String id) {
71          QueryByCriteria.Builder criteria = QueryByCriteria.Builder.create();
72          criteria.setPredicates(equal(NotificationConstants.BO_PROPERTY_NAMES.DELIVERY_SYSTEM_ID, id));
73          Collection<NotificationMessageDelivery> results = dataObjectService.findMatching(NotificationMessageDelivery.class, criteria.build()).getResults();
74  
75          if (results.isEmpty()) {
76              return null;
77          }
78          if (results.size() > 1) {
79              throw new RuntimeException("More than one message delivery found with the following delivery system id: " + id);
80          }
81  
82          return results.iterator().next();
83      }
84  
85      /**
86       * @see org.kuali.rice.ken.service.NotificationMessageDeliveryService#getNotificationMessageDeliveries()
87       */
88      public Collection<NotificationMessageDelivery> getNotificationMessageDeliveries() {
89          return dataObjectService.findMatching(NotificationMessageDelivery.class, QueryByCriteria.Builder.create().build()).getResults();
90      }
91      
92      /**
93       * @see org.kuali.rice.ken.service.NotificationMessageDeliveryService#getNotificationMessageDeliveries(java.lang.Long, java.lang.String)
94       */
95      //switch to JPA criteria
96      @Override
97      public Collection<NotificationMessageDelivery> getNotificationMessageDeliveries(NotificationBo notification, String userRecipientId) {
98  
99          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 }