Skip to content

Commit c7d69c1

Browse files
committed
SAK-51956 motifications Add broadcast type notification
https://sakaiproject.atlassian.net/browse/SAK-51956 The idea behind this change is to replace the MOTD type notifications with a single db entry rather than one for each system user. This change also creates a SchedulingService which provides a facade onto a ScheduledExecutorService and updates all the uses of scheduled executors across Sakai to use it.
1 parent 0cdfff1 commit c7d69c1

File tree

41 files changed

+647
-329
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+647
-329
lines changed

announcement/announcement-api/api/src/java/org/sakaiproject/announcement/api/AnnouncementsUserNotificationHandler.java

Lines changed: 136 additions & 113 deletions
Large diffs are not rendered by default.

assignment/api/src/java/org/sakaiproject/assignment/api/AddAssignmentUserNotificationHandler.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ private List<UserNotificationData> handleAdd(String from, String siteId, String
127127
if (groupIds.isEmpty() || groupsUsers.contains(to)) {
128128
if (!from.equals(to) && !securityService.isSuperUser(to)) {
129129
String url = assignmentService.getDeepLink(siteId, assignmentId, to);
130-
bhEvents.add(new UserNotificationData(from, to, siteId, title, url, AssignmentConstants.TOOL_ID));
130+
bhEvents.add(new UserNotificationData(from, to, siteId, title, url, AssignmentConstants.TOOL_ID, false, null));
131131
}
132132
}
133133
}
@@ -164,7 +164,7 @@ private List<UserNotificationData> handleUpdateAccess(String from, String ref, S
164164
String to = u.getId();
165165
if (!from.equals(to) && !securityService.isSuperUser(to)) {
166166
String url = assignmentService.getDeepLink(siteId, assignmentId, to);
167-
bhEvents.add(new UserNotificationData(from, to, siteId, title, url, AssignmentConstants.TOOL_ID));
167+
bhEvents.add(new UserNotificationData(from, to, siteId, title, url, AssignmentConstants.TOOL_ID, false, null));
168168
}
169169
}
170170
} else {
@@ -178,7 +178,7 @@ private List<UserNotificationData> handleUpdateAccess(String from, String ref, S
178178
String to = u.getId();
179179
if (!from.equals(to) && !securityService.isSuperUser(to)) {
180180
String url = assignmentService.getDeepLink(siteId, assignmentId, to);
181-
bhEvents.add(new UserNotificationData(from, to, siteId, title, url, AssignmentConstants.TOOL_ID));
181+
bhEvents.add(new UserNotificationData(from, to, siteId, title, url, AssignmentConstants.TOOL_ID, false, null));
182182
}
183183
}
184184
}

assignment/api/src/java/org/sakaiproject/assignment/api/GradeAssignmentUserNotificationHandler.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ public Optional<List<UserNotificationData>> handleEvent(Event e) {
9494
try {
9595
String url = assignmentService.getDeepLink(siteId, assignment.getId(), to.getSubmitter());
9696
if (StringUtils.isNotBlank(url)) {
97-
bhEvents.add(new UserNotificationData(from, to.getSubmitter(), siteId, title, url, AssignmentConstants.TOOL_ID));
97+
bhEvents.add(new UserNotificationData(from, to.getSubmitter(), siteId, title, url, AssignmentConstants.TOOL_ID, false, null));
9898
}
9999
} catch(Exception exc) {
100100
log.error("Error retrieving deep link for assignment {} and user {} on site {}", assignment.getId(), to.getSubmitter(), siteId, exc);

commons/api/src/java/org/sakaiproject/commons/api/CommonsCommentUserNotificationHandler.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ public Optional<List<UserNotificationData>> handleEvent(Event e) {
9191

9292
// First, send an alert to the post author
9393
if (!commentCreator.equals(postCreator)) {
94-
bhEvents.add(new UserNotificationData(commentCreator, postCreator, siteId, siteTitle, url, CommonsConstants.TOOL_ID));
94+
bhEvents.add(new UserNotificationData(commentCreator, postCreator, siteId, siteTitle, url, CommonsConstants.TOOL_ID, false, null));
9595
}
9696

9797
List<String> sentAlready = new ArrayList<>();
@@ -107,7 +107,7 @@ public Optional<List<UserNotificationData>> handleEvent(Event e) {
107107
}
108108

109109
if (!sentAlready.contains(to)) {
110-
bhEvents.add(new UserNotificationData(commentCreator, to, siteId, siteTitle, url, CommonsConstants.TOOL_ID));
110+
bhEvents.add(new UserNotificationData(commentCreator, to, siteId, siteTitle, url, CommonsConstants.TOOL_ID, false, null));
111111
sentAlready.add(to);
112112
}
113113
}

config/configuration/bundles/src/bundle/org/sakaiproject/config/bundle/default.sakai.properties

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2255,6 +2255,10 @@
22552255
# DEFAULT: false
22562256
# announcement.notification.email.to.matches.from=true
22572257

2258+
# Controls how long a MOTD user notification lives, in hours, before being cleaned up
2259+
# DEFAULT: 24
2260+
# announcement.motd.notification.ttlhours=1
2261+
22582262
## BASICLTI PROVIDER
22592263

22602264
# Enable the Provider
@@ -5765,3 +5769,17 @@
57655769
# on a production system. If there is no PNP base URL, this value has no effect.
57665770
# lti.pnp.use_email=false
57675771
# DEFAULT: false
5772+
5773+
5774+
# Set the delay period between expired notifications
5775+
# DEFAULT: 30
5776+
# messaging.delete.expired.periodminutes=10
5777+
5778+
# Set the number of threads pooled for use by the user messaging service. An executor will use these
5779+
# threads to send emails or digests to users
5780+
# DEFAULT: 10
5781+
# messaging.threadpool.size=4
5782+
5783+
# Configure the thread pool size for the scheduling service.
5784+
# DEFAULT: 8
5785+
# schedulingservice.poolsize=4

kernel/api/src/main/java/org/sakaiproject/messaging/api/UserMessagingService.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ public interface UserMessagingService {
6262
/**
6363
* @return the list of notifications for the current user
6464
*/
65-
public List<UserNotification> getNotifications();
65+
public List<UserNotificationTransferBean> getNotifications();
6666

6767
/**
6868
* Register a handler for broadcast messages. The first registered handler that

kernel/api/src/main/java/org/sakaiproject/messaging/api/UserNotificationData.java

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,15 @@
1515
*/
1616
package org.sakaiproject.messaging.api;
1717

18+
import java.time.Duration;
19+
1820
import lombok.AllArgsConstructor;
19-
import lombok.Getter;
21+
import lombok.NoArgsConstructor;
22+
import lombok.Data;
2023

21-
@AllArgsConstructor @Getter
24+
@AllArgsConstructor
25+
@NoArgsConstructor
26+
@Data
2227
public class UserNotificationData {
2328

2429
private String from;
@@ -27,4 +32,6 @@ public class UserNotificationData {
2732
private String title;
2833
private String url;
2934
private String commonToolId;
35+
private boolean broadcast;
36+
private Duration ttl;
3037
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/**
2+
* Copyright (c) 2003-2019 The Apereo 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://opensource.org/licenses/ecl2
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.sakaiproject.messaging.api;
17+
18+
import org.sakaiproject.messaging.api.model.UserNotification;
19+
20+
import java.time.Instant;
21+
22+
public class UserNotificationTransferBean {
23+
24+
public String from;
25+
public String to;
26+
public String event;
27+
public String ref;
28+
public String title;
29+
public String siteId;
30+
public String url;
31+
public Instant eventDate;
32+
public boolean viewed;
33+
public String tool;
34+
public boolean broadcast;
35+
36+
public String fromDisplayName;
37+
public String siteTitle;
38+
public String formattedEventDate;
39+
40+
public static UserNotificationTransferBean of(UserNotification un) {
41+
42+
UserNotificationTransferBean bean = new UserNotificationTransferBean();
43+
bean.from = un.getFromUser();
44+
bean.to = un.getToUser();
45+
bean.event = un.getEvent();
46+
bean.ref = un.getRef();
47+
bean.title = un.getTitle();
48+
bean.siteId = un.getSiteId();
49+
bean.url = un.getUrl();
50+
bean.eventDate = un.getEventDate();
51+
bean.viewed = un.getViewed();
52+
bean.tool = un.getTool();
53+
bean.broadcast = un.getBroadcast();
54+
return bean;
55+
}
56+
}

kernel/api/src/main/java/org/sakaiproject/messaging/api/model/UserNotification.java

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525
import javax.persistence.Index;
2626
import javax.persistence.SequenceGenerator;
2727
import javax.persistence.Table;
28-
import javax.persistence.Transient;
2928

3029
import org.sakaiproject.springframework.data.PersistableEntity;
3130

@@ -68,13 +67,17 @@ public class UserNotification implements PersistableEntity<Long> {
6867
@Column(name="SITE_ID", length = 99)
6968
private String siteId;
7069

71-
@Column(name="URL", length = 2048, nullable = false)
70+
@Column(name="URL", length = 2048)
7271
private String url;
7372

7473
@Column(name="EVENT_DATE", nullable = false)
7574
@Type(type = "org.hibernate.type.InstantType")
7675
private Instant eventDate;
7776

77+
@Column(name="END_DATE")
78+
@Type(type = "org.hibernate.type.InstantType")
79+
private Instant endDate;
80+
7881
@Column(name="DEFERRED", nullable = false)
7982
private Boolean deferred = Boolean.FALSE;
8083

@@ -84,12 +87,6 @@ public class UserNotification implements PersistableEntity<Long> {
8487
@Column(name = "TOOL", length = 99)
8588
private String tool;
8689

87-
@Transient
88-
private String fromDisplayName;
89-
90-
@Transient
91-
private String formattedEventDate;
92-
93-
@Transient
94-
private String siteTitle;
90+
@Column(name = "BROADCAST")
91+
private Boolean broadcast = Boolean.FALSE;
9592
}

kernel/api/src/main/java/org/sakaiproject/messaging/api/repository/UserNotificationRepository.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,9 @@
2424
public interface UserNotificationRepository extends SpringCrudRepository<UserNotification, Long> {
2525

2626
List<UserNotification> findByToUser(String toUser);
27+
List<UserNotification> findByBroadcast(boolean broadcast);
2728
int deleteByToUserAndDeferred(String userId, boolean deferred);
29+
int deleteExpiredNotifications();
2830
int setAllNotificationsViewed(String userId, String siteId, String toolId);
2931
int setDeferredBySiteId(String siteId, boolean deferred);
3032
}

0 commit comments

Comments
 (0)