r1660 - in trunk/src: main/java/cc/kune/core/server/notifier main/java/cc/kune/core/server/scheduler main/java/cc/kune/wave/server/kspecific test/java/cc/kune/core/server/notifier
Author: vjrj_ Date: 2012-01-12 15:05:46 +0100 (Thu, 12 Jan 2012) New Revision: 1660 Added: trunk/src/main/java/cc/kune/core/server/notifier/PendingNotificationProvider.java Modified: trunk/src/main/java/cc/kune/core/server/notifier/NotificationSenderDefault.java trunk/src/main/java/cc/kune/core/server/notifier/PendingNotification.java trunk/src/main/java/cc/kune/core/server/notifier/PendingNotificationSender.java trunk/src/main/java/cc/kune/core/server/scheduler/CronServerTasksManager.java trunk/src/main/java/cc/kune/wave/server/kspecific/WaveEmailNotifier.java trunk/src/test/java/cc/kune/core/server/notifier/PendingNotificationSenderTest.java Log: NEW - # 185: Implement notification levels (hourly and daily) similar to Google Wave http://kune.ourproject.org/issues/ticket/185 Modified: trunk/src/main/java/cc/kune/core/server/notifier/NotificationSenderDefault.java =================================================================== --- trunk/src/main/java/cc/kune/core/server/notifier/NotificationSenderDefault.java 2012-01-12 04:14:28 UTC (rev 1659) +++ trunk/src/main/java/cc/kune/core/server/notifier/NotificationSenderDefault.java 2012-01-12 14:05:46 UTC (rev 1660) @@ -51,7 +51,7 @@ private boolean noOnline(final String username) { final boolean logged = usersOnline.isLogged(username); - LOG.debug(String.format("User '' is online for notifications? %s", username, logged)); + LOG.debug(String.format("User '%s' is online for notifications? %s", username, logged)); return !logged; } Modified: trunk/src/main/java/cc/kune/core/server/notifier/PendingNotification.java =================================================================== --- trunk/src/main/java/cc/kune/core/server/notifier/PendingNotification.java 2012-01-12 04:14:28 UTC (rev 1659) +++ trunk/src/main/java/cc/kune/core/server/notifier/PendingNotification.java 2012-01-12 14:05:46 UTC (rev 1660) @@ -8,6 +8,13 @@ */ public class PendingNotification { + /** + * The Constant NONE is used when for instance, all the destinations are not + * local, so, we should not notify them by email + */ + public static final PendingNotification NONE = new PendingNotification(null, null, null, false, false, + null); + /** The body. */ private final FormatedString body; Added: trunk/src/main/java/cc/kune/core/server/notifier/PendingNotificationProvider.java =================================================================== --- trunk/src/main/java/cc/kune/core/server/notifier/PendingNotificationProvider.java (rev 0) +++ trunk/src/main/java/cc/kune/core/server/notifier/PendingNotificationProvider.java 2012-01-12 14:05:46 UTC (rev 1660) @@ -0,0 +1,11 @@ +package cc.kune.core.server.notifier; + +import com.google.inject.Provider; + +/** + * The Class PendingNotificationProvider is used to generate notifications in a + * deferred way of waves updates (for instance) + */ +public abstract class PendingNotificationProvider implements Provider<PendingNotification> { + +} Modified: trunk/src/main/java/cc/kune/core/server/notifier/PendingNotificationSender.java =================================================================== --- trunk/src/main/java/cc/kune/core/server/notifier/PendingNotificationSender.java 2012-01-12 04:14:28 UTC (rev 1659) +++ trunk/src/main/java/cc/kune/core/server/notifier/PendingNotificationSender.java 2012-01-12 14:05:46 UTC (rev 1660) @@ -19,16 +19,18 @@ public class PendingNotificationSender { /** The Constant NO_NEXT. */ - private static final Collection<PendingNotification> NO_NEXT = null; + private static final Collection<PendingNotificationProvider> NO_NEXT = null; + // FIXME this should be in DB so we'll don't lose them in server restarts /** The daily pend notif. list */ - private final Set<PendingNotification> dailyPendNotif; + private final Set<PendingNotificationProvider> dailyPendNotif; + // FIXME this should be in DB so we'll don't lose them in server restarts /** The houry pend notif. list */ - private final Set<PendingNotification> hourlyPendNotif; + private final Set<PendingNotificationProvider> hourlyPendNotif; /** The immediate pend notif. list */ - private final Set<PendingNotification> immediatePendNotif; + private final Set<PendingNotificationProvider> immediatePendNotif; /** The sender. */ private final NotificationSender sender; @@ -42,15 +44,20 @@ @Inject public PendingNotificationSender(final NotificationSender sender) { this.sender = sender; - immediatePendNotif = new HashSet<PendingNotification>(); - hourlyPendNotif = new HashSet<PendingNotification>(); - dailyPendNotif = new HashSet<PendingNotification>(); + immediatePendNotif = new HashSet<PendingNotificationProvider>(); + hourlyPendNotif = new HashSet<PendingNotificationProvider>(); + dailyPendNotif = new HashSet<PendingNotificationProvider>(); } public void add(final NotificationType type, final FormatedString subject, final FormatedString body, final boolean isHtml, final boolean forceSend, final User to) { - add(new PendingNotification(type, subject, body, isHtml, forceSend, - new SimpleDestinationProvider(to))); + add(new PendingNotificationProvider() { + @Override + public PendingNotification get() { + return new PendingNotification(type, subject, body, isHtml, forceSend, + new SimpleDestinationProvider(to)); + } + }); } /** @@ -59,10 +66,10 @@ * @param notification * the notification */ - public void add(final PendingNotification notification) { - if (!hourlyPendNotif.contains(notification)) { + public void add(final PendingNotificationProvider notificationProv) { + if (!hourlyPendNotif.contains(notificationProv)) { // If we have send a similar notification this hour just ignore - immediatePendNotif.add(notification); + immediatePendNotif.add(notificationProv); } } @@ -106,14 +113,18 @@ * The current frequency of notifications, that is, we'll send * notifications only to users with this frequency configured */ - private void send(final Collection<PendingNotification> list, - final Collection<PendingNotification> nextList, final EmailNotificationFrequency currentFreq) { - for (final PendingNotification notification : list) { - sender.send(notification, currentFreq); - if (!notification.isForceSend() && nextList != NO_NEXT) { - // Forced Send, are send immediately (independent of how User has its - // notification configured)! - nextList.add(notification); + private void send(final Collection<PendingNotificationProvider> list, + final Collection<PendingNotificationProvider> nextList, + final EmailNotificationFrequency currentFreq) { + for (final PendingNotificationProvider notificationProv : list) { + final PendingNotification notification = notificationProv.get(); + if (!notification.equals(PendingNotification.NONE)) { + sender.send(notification, currentFreq); + if (!notification.isForceSend() && nextList != NO_NEXT) { + // Forced Send, are send immediately (independent of how User has its + // notification configured)! + nextList.add(notificationProv); + } } } list.clear(); Modified: trunk/src/main/java/cc/kune/core/server/scheduler/CronServerTasksManager.java =================================================================== --- trunk/src/main/java/cc/kune/core/server/scheduler/CronServerTasksManager.java 2012-01-12 04:14:28 UTC (rev 1659) +++ trunk/src/main/java/cc/kune/core/server/scheduler/CronServerTasksManager.java 2012-01-12 14:05:46 UTC (rev 1660) @@ -55,7 +55,7 @@ LOG.info("Starting cron manager"); try { sched.start(); - scheduleJob(PendingNotificationImmediateJob.class, "0 */2 * * * ?", "pendinnotifimmediate"); + scheduleJob(PendingNotificationImmediateJob.class, "0 */1 * * * ?", "pendinnotifimmediate"); scheduleJob(PendingNotificationHourlyJob.class, "0 0 * * * ?", "pendingnotifhourly"); scheduleJob(ClearUpdatedWavesHourlyJob.class, "0 0 * * * ?", "clearupdatedwaveshourly"); scheduleJob(PendingNotificationDailyJob.class, "0 5 0 * * ?", "pendingnotifdaily"); Modified: trunk/src/main/java/cc/kune/wave/server/kspecific/WaveEmailNotifier.java =================================================================== --- trunk/src/main/java/cc/kune/wave/server/kspecific/WaveEmailNotifier.java 2012-01-12 04:14:28 UTC (rev 1659) +++ trunk/src/main/java/cc/kune/wave/server/kspecific/WaveEmailNotifier.java 2012-01-12 14:05:46 UTC (rev 1660) @@ -27,6 +27,7 @@ import cc.kune.core.server.mail.FormatedString; import cc.kune.core.server.notifier.NotificationType; import cc.kune.core.server.notifier.PendingNotification; +import cc.kune.core.server.notifier.PendingNotificationProvider; import cc.kune.core.server.notifier.PendingNotificationSender; import cc.kune.core.server.notifier.SimpleDestinationProvider; import cc.kune.core.server.notifier.WaveDestinationProvider; @@ -76,29 +77,35 @@ final String siteUrl = basicProperties.getSiteUrl(); waveBus.subscribe(new Subscriber() { - private void addPendingNotif(final ParticipantId participant, final FormatedString subject, - final FormatedString body) { + private PendingNotification createPendingNotif(final ParticipantId participant, + final FormatedString subject, final FormatedString body) { final String address = participant.getAddress(); if (partUtils.isLocal(address)) { final String userName = partUtils.getAddressName(address); try { final User user = userFinder.findByShortName(userName); - notificator.add(new PendingNotification(NotificationType.email, subject, body, true, false, - new SimpleDestinationProvider(user))); + return new PendingNotification(NotificationType.email, subject, body, true, false, + new SimpleDestinationProvider(user)); } catch (final NoResultException e) { // Seems is not a local user } } + return PendingNotification.NONE; } + private String getTitle(final ReadableWaveletData wavelet, final ParticipantId by) { + return waveService.getTitle(WaveRef.of(wavelet.getWaveId(), wavelet.getWaveletId()), + by.toString()); + } + private String getUrl(final ReadableWaveletData wavelet, final WaveletId waveletId) { return KuneWaveServerUtils.getUrl(WaveRef.of(wavelet.getWaveId(), waveletId)); } - private FormatedString newWaveTemplate(final String url) { + private FormatedString newWaveTemplate(final String by, final String url) { return FormatedString.build( - "Hi there,<br><br>You have a new message in your inbox at %s. <a href=\"%s#%s\">Read more</a>.<br>", - siteCommonName, siteUrl, url); + "Hi there,<br><br>You have a new message by '%s' in your inbox at %s. <a href=\"%s#%s\">Read more</a>.<br>", + by, siteCommonName, siteUrl, url); } private FormatedString removeWaveTemplate(final String by, final String title) { @@ -107,10 +114,10 @@ by, title, siteCommonName, siteUrl, SiteTokens.WAVEINBOX); } - private FormatedString updatedWaveTemplate(final String by, final String url) { + private FormatedString updatedWaveTemplate(final String by, final String title, final String url) { return FormatedString.build( - "Hi there,<br><br>You have an updated message by '%s' in your inbox at %s. <a href=\"%s#%s\">Read more</a>.<br>", - by, siteCommonName, siteUrl, url); + "Hi there,<br><br>The message '%s' was updated by '%s' in your inbox at %s. <a href=\"%s#%s\">Read more</a>.<br>", + title, by, siteCommonName, siteUrl, url); } @Override @@ -126,29 +133,57 @@ for (final TransformedWaveletDelta delta : deltas) { for (final WaveletOperation op : delta) { if (op instanceof AddParticipant) { - final ParticipantId participant = ((AddParticipant) op).getParticipantId(); - addPendingNotif(participant, FormatedString.build("You have a new message"), - newWaveTemplate(getUrl(wavelet, waveletId))); + notificator.add(new PendingNotificationProvider() { + @Override + public PendingNotification get() { + final AddParticipant addParticipantOp = (AddParticipant) op; + final ParticipantId by = addParticipantOp.getContext().getCreator(); + final ParticipantId to = addParticipantOp.getParticipantId(); + LOG.info(String.format("New wave from '%s' to '%s'", by, to)); + return createPendingNotif(to, FormatedString.build("You have a new message"), + newWaveTemplate(by.toString(), getUrl(wavelet, waveletId))); + } + }); } else if (op instanceof RemoveParticipant) { - final ParticipantId participant = ((RemoveParticipant) op).getParticipantId(); - final ParticipantId by = ((RemoveParticipant) op).getContext().getCreator(); - final String title = waveService.getTitle(WaveRef.of(wavelet.getWaveId(), waveletId), - by.toString()); - addPendingNotif(participant, FormatedString.build("You have been removed from message"), - removeWaveTemplate(by.toString(), title)); + notificator.add(new PendingNotificationProvider() { + @Override + public PendingNotification get() { + final RemoveParticipant removeParticipantOp = (RemoveParticipant) op; + final ParticipantId by = removeParticipantOp.getContext().getCreator(); + final ParticipantId to = removeParticipantOp.getParticipantId(); + final String title = getTitle(wavelet, by); + LOG.info(String.format("'%s' removed from wave '%s' to '%s'", by, title, to)); + return createPendingNotif(to, + FormatedString.build("You have been removed from message"), + removeWaveTemplate(by.toString(), title)); + } + }); } else if (op instanceof WaveletBlipOperation) { + // Replies, etc final WaveId waveId = wavelet.getWaveId(); if (!updatedWavesInLastHour.contains(waveId)) { updatedWavesInLastHour.add(waveId); - // Replies, etc - final ParticipantId by = ((WaveletBlipOperation) op).getContext().getCreator(); - // Duplicate code above - final WaveRef waveref = WaveRef.of(waveId, waveletId); - final String url = KuneWaveServerUtils.getUrl(waveref); - notificator.add(new PendingNotification(NotificationType.email, - FormatedString.build("You have an updated message"), updatedWaveTemplate( - by.toString(), url), true, false, new WaveDestinationProvider(waveref, - by.toString()))); + notificator.add(new PendingNotificationProvider() { + @Override + public PendingNotification get() { + final WaveRef waveref = WaveRef.of(waveId, waveletId); + final ParticipantId by = ((WaveletBlipOperation) op).getContext().getCreator(); + final String title = getTitle(wavelet, by); + final String url = KuneWaveServerUtils.getUrl(waveref); + LOG.info(String.format("'%s' updated wave '%s'", by, title)); + return new PendingNotification(NotificationType.email, + FormatedString.build("You have an updated message"), updatedWaveTemplate( + by.toString(), title, url), true, false, new WaveDestinationProvider( + waveref, by.toString())); + } + }); + // notificator.add(new + // PendingNotification(NotificationType.email, + // FormatedString.build("You have an updated message"), + // updatedWaveTemplate( + // by.toString(), title, url), true, false, new + // WaveDestinationProvider(waveref, + // by.toString()))); } } } Modified: trunk/src/test/java/cc/kune/core/server/notifier/PendingNotificationSenderTest.java =================================================================== --- trunk/src/test/java/cc/kune/core/server/notifier/PendingNotificationSenderTest.java 2012-01-12 04:14:28 UTC (rev 1659) +++ trunk/src/test/java/cc/kune/core/server/notifier/PendingNotificationSenderTest.java 2012-01-12 14:05:46 UTC (rev 1660) @@ -15,10 +15,10 @@ private static final FormatedString OTHER_SUBJECT = FormatedString.build("Some other subject"); private static final FormatedString SUBJECT = FormatedString.build("Some subject"); private PendingNotificationSender manager; - private PendingNotification otherNotif; + private PendingNotificationProvider otherNotif; private NotificationSender sender; - private PendingNotification someForcedNotif; - private PendingNotification someNotif; + private PendingNotificationProvider someForcedNotif; + private PendingNotificationProvider someNotif; private void assertQueues(final int i, final int j, final int k) { // TODO Auto-generated method stub @@ -32,12 +32,28 @@ public void before() { sender = Mockito.mock(NotificationSender.class); manager = new PendingNotificationSender(sender); - someNotif = new PendingNotification(NotificationType.email, SUBJECT, BODY, false, false, - someUserProvider); - otherNotif = new PendingNotification(NotificationType.email, OTHER_SUBJECT, OTHER_BODY, false, - false, someUserProvider); - someForcedNotif = new PendingNotification(NotificationType.email, SUBJECT, BODY, false, true, - someUserProvider); + otherNotif = new PendingNotificationProvider() { + @Override + public PendingNotification get() { + return new PendingNotification(NotificationType.email, OTHER_SUBJECT, OTHER_BODY, false, false, + someUserProvider); + } + }; + someForcedNotif = new PendingNotificationProvider() { + @Override + public PendingNotification get() { + return new PendingNotification(NotificationType.email, SUBJECT, BODY, false, true, + someUserProvider); + } + }; + + someNotif = new PendingNotificationProvider() { + @Override + public PendingNotification get() { + return new PendingNotification(NotificationType.email, SUBJECT, BODY, false, false, + someUserProvider); + } + }; } @Test
participants (1)
-
Vicente J. Ruiz Jurado