1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.rice.ken.service.impl;
17
18 import org.kuali.rice.core.api.criteria.QueryByCriteria;
19 import org.kuali.rice.core.api.util.xml.XmlException;
20 import org.kuali.rice.ken.bo.NotificationBo;
21 import org.kuali.rice.ken.bo.NotificationMessageDelivery;
22 import org.kuali.rice.ken.bo.NotificationRecipientBo;
23 import org.kuali.rice.ken.bo.NotificationSenderBo;
24 import org.kuali.rice.ken.dao.NotificationDao;
25 import org.kuali.rice.ken.bo.NotificationResponseBo;
26 import org.kuali.rice.ken.deliverer.impl.KEWActionListMessageDeliverer;
27 import org.kuali.rice.ken.service.NotificationAuthorizationService;
28 import org.kuali.rice.ken.service.NotificationMessageContentService;
29 import org.kuali.rice.ken.service.NotificationMessageDeliveryService;
30 import org.kuali.rice.ken.service.NotificationRecipientService;
31 import org.kuali.rice.ken.service.NotificationService;
32 import org.kuali.rice.ken.util.NotificationConstants;
33 import org.kuali.rice.krad.data.DataObjectService;
34
35 import java.io.IOException;
36 import java.sql.Timestamp;
37 import java.util.ArrayList;
38 import java.util.Collection;
39 import java.util.Collections;
40 import java.util.List;
41
42 import static org.kuali.rice.core.api.criteria.PredicateFactory.equal;
43
44
45
46
47
48 public class NotificationServiceImpl implements NotificationService {
49 private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger
50 .getLogger(NotificationServiceImpl.class);
51
52 private DataObjectService dataObjectService;
53 private NotificationDao notDao;
54 private NotificationMessageContentService messageContentService;
55 private NotificationAuthorizationService notificationAuthorizationService;
56 private NotificationRecipientService notificationRecipientService;
57 private NotificationMessageDeliveryService notificationMessageDeliveryService;
58
59
60
61
62
63
64
65
66
67 public NotificationServiceImpl(DataObjectService dataObjectService, NotificationMessageContentService messageContentService,
68 NotificationAuthorizationService notificationAuthorizationService, NotificationRecipientService notificationRecipientService,
69 NotificationMessageDeliveryService notificationMessageDeliveryService,
70 NotificationDao notDao) {
71 this.dataObjectService = dataObjectService;
72 this.messageContentService = messageContentService;
73 this.notificationAuthorizationService = notificationAuthorizationService;
74 this.notificationRecipientService = notificationRecipientService;
75 this.notificationMessageDeliveryService = notificationMessageDeliveryService;
76 this.notDao = notDao;
77 }
78
79
80
81
82
83 @Override
84 public NotificationBo getNotification(Long id) {
85
86 return dataObjectService.find(NotificationBo.class, id);
87
88 }
89
90
91
92
93
94
95
96
97 @Override
98 public NotificationResponseBo sendNotification(String notificationMessageAsXml) throws IOException, XmlException {
99
100 NotificationBo notification = messageContentService.parseNotificationRequestMessage(notificationMessageAsXml);
101
102
103 return sendNotification(notification);
104 }
105
106
107
108
109 @Override
110 public NotificationResponseBo sendNotification(NotificationBo notification) {
111 NotificationResponseBo response = new NotificationResponseBo();
112
113
114 boolean producerAuthorizedForChannel = notificationAuthorizationService.isProducerAuthorizedToSendNotificationForChannel(notification.getProducer(), notification.getChannel());
115 if(!producerAuthorizedForChannel) {
116 LOG.error("Producer " + notification.getProducer() + " is not authorized to send messages to channel " + notification.getChannel());
117 response.setStatus(NotificationConstants.RESPONSE_STATUSES.FAILURE);
118 response.setMessage(NotificationConstants.RESPONSE_MESSAGES.PRODUCER_NOT_AUTHORIZED_FOR_CHANNEL);
119 return response;
120 }
121
122
123 for(int i = 0; i < notification.getRecipients().size(); i++) {
124 NotificationRecipientBo recipient = notification.getRecipient(i);
125 if (recipient.getNotification() == null) {
126 recipient.setNotification(notification);
127 }
128 boolean validRecipient = notificationRecipientService.isRecipientValid(recipient.getRecipientId(), recipient.getRecipientType());
129 if(!validRecipient) {
130 response.setStatus(NotificationConstants.RESPONSE_STATUSES.FAILURE);
131 response.setMessage(NotificationConstants.RESPONSE_MESSAGES.INVALID_RECIPIENT + " - recipientId=" +
132 recipient.getRecipientId() + ", recipientType=" + recipient.getRecipientType());
133 return response;
134 }
135 }
136
137
138 for (NotificationSenderBo sender : notification.getSenders()) {
139 sender.setNotification(notification);
140 }
141
142
143 if (notification.getCreationDateTime() == null) {
144 notification.setCreationDateTimeValue(new Timestamp(System.currentTimeMillis()));
145 }
146
147
148 if(notification.getSendDateTime() == null) {
149 notification.setSendDateTimeValue(new Timestamp(System.currentTimeMillis()));
150 }
151
152
153 if (notification.getAutoRemoveDateTime() != null) {
154 if (notification.getAutoRemoveDateTimeValue().before(notification.getSendDateTimeValue())) {
155 response.setStatus(NotificationConstants.RESPONSE_STATUSES.FAILURE);
156 response.setMessage(NotificationConstants.RESPONSE_MESSAGES.INVALID_REMOVE_DATE);
157 return response;
158 }
159 }
160
161
162 if(!notification.getDeliveryType().equalsIgnoreCase(NotificationConstants.DELIVERY_TYPES.ACK) &&
163 !notification.getDeliveryType().equalsIgnoreCase(NotificationConstants.DELIVERY_TYPES.FYI)) {
164 response.setStatus(NotificationConstants.RESPONSE_STATUSES.FAILURE);
165 response.setMessage(NotificationConstants.RESPONSE_MESSAGES.INVALID_DELIVERY_TYPE + " - deliveryType=" +
166 notification.getDeliveryType());
167 return response;
168 }
169
170
171 try {
172 notification = dataObjectService.save(notification);
173 } catch(Exception e) {
174 response.setStatus(NotificationConstants.RESPONSE_STATUSES.FAILURE);
175 response.setMessage(NotificationConstants.RESPONSE_MESSAGES.ERROR_SAVING_NOTIFICATION);
176 return response;
177 }
178
179
180 response.setMessage(NotificationConstants.RESPONSE_MESSAGES.SUCCESSFULLY_RECEIVED);
181 response.setNotificationId(notification.getId());
182 return response;
183 }
184
185
186
187
188
189 @Override
190 public Collection getNotificationsForRecipientByType(String contentTypeName, String recipientId) {
191 QueryByCriteria.Builder criteria = QueryByCriteria.Builder.create();
192 criteria.setPredicates(equal(NotificationConstants.BO_PROPERTY_NAMES.CONTENT_TYPE_NAME, contentTypeName),
193 equal(NotificationConstants.BO_PROPERTY_NAMES.RECIPIENTS_RECIPIENT_ID, recipientId));
194
195 return Collections.unmodifiableCollection(dataObjectService.findMatching(NotificationBo.class, criteria.build()).getResults());
196 }
197
198
199
200
201 @Override
202 public void dismissNotificationMessageDelivery(Long id, String user, String cause) {
203
204 NotificationMessageDelivery nmd = notificationMessageDeliveryService.getNotificationMessageDelivery(id);
205 dismissNotificationMessageDelivery(nmd, user, cause);
206 }
207
208
209
210
211 public void dismissNotificationMessageDelivery(NotificationMessageDelivery nmd, String user, String cause) {
212
213 NotificationBo notification = nmd.getNotification();
214
215
216 Collection<NotificationMessageDelivery> userDeliveries = notificationMessageDeliveryService.getNotificationMessageDeliveries(notification, nmd.getUserRecipientId());
217
218 final String targetStatus;
219
220
221 if (NotificationConstants.AUTO_REMOVE_CAUSE.equals(cause)) {
222 targetStatus = NotificationConstants.MESSAGE_DELIVERY_STATUS.AUTO_REMOVED;
223 } else {
224 targetStatus = NotificationConstants.MESSAGE_DELIVERY_STATUS.REMOVED;
225 }
226
227 KEWActionListMessageDeliverer deliverer = new KEWActionListMessageDeliverer();
228
229
230 for (NotificationMessageDelivery messageDelivery: userDeliveries) {
231
232
233 if (!NotificationConstants.MESSAGE_DELIVERY_STATUS.DELIVERED.equals(messageDelivery.getMessageDeliveryStatus())) {
234 LOG.info("Skipping dismissal of non-delivered message delivery #" + messageDelivery.getId());
235 } else if (targetStatus.equals(messageDelivery.getMessageDeliveryStatus())) {
236 LOG.info("Skipping dismissal of already removed message delivery #" + messageDelivery.getId());
237 } else {
238 LOG.debug("Dismissing message delivery #" + messageDelivery.getId() + " " + messageDelivery.getVersionNumber());
239
240
241
242 deliverer.dismissMessageDelivery(messageDelivery, user, cause);
243
244
245
246
247 }
248
249
250
251
252
253 messageDelivery.setMessageDeliveryStatus(targetStatus);
254
255
256
257 LOG.debug("Saving message delivery #" + messageDelivery.getId() + " " + messageDelivery.getVersionNumber());
258 messageDelivery = dataObjectService.save(messageDelivery);
259
260 LOG.debug("Message delivery '" + messageDelivery.getId() + "' for notification '" + messageDelivery.getNotification().getId() + "' was successfully dismissed.");
261 }
262 }
263
264
265
266
267
268
269
270
271
272
273 @Override
274 public Collection<NotificationBo> takeNotificationsForResolution() {
275
276 Collection<NotificationBo> available_notifications = notDao.findMatchedNotificationsForResolution(new Timestamp(System.currentTimeMillis()), dataObjectService);
277 List<NotificationBo> savedNotifications = new ArrayList<NotificationBo>();
278
279
280
281 if (available_notifications != null) {
282 for (NotificationBo notification: available_notifications) {
283 LOG.info("notification: " + notification);
284 notification.setLockedDateValue(new Timestamp(System.currentTimeMillis()));
285 savedNotifications.add(dataObjectService.save(notification));
286 }
287 }
288
289 return savedNotifications;
290 }
291
292
293
294
295
296
297 @Override
298 public void unlockNotification(NotificationBo notification) {
299 Collection<NotificationBo> notifications = notDao.findMatchedNotificationsForUnlock(notification, dataObjectService);
300
301 if (notifications == null || notifications.size() == 0) {
302 throw new RuntimeException("Notification #" + notification.getId() + " not found to unlock");
303 }
304
305 NotificationBo n = notifications.iterator().next();
306 n.setLockedDateValue(null);
307
308 dataObjectService.save(n);
309 }
310 }