Author: tchemit Date: 2012-12-01 13:34:54 +0100 (Sat, 01 Dec 2012) New Revision: 3761 Url: http://chorem.org/projects/pollen/repository/revisions/3761 Log: fixes #850: Send reminder emails work very well (send message all 10min) Modified: trunk/pollen-persistence/src/main/java/org/chorem/pollen/business/persistence/PollDAOImpl.java trunk/pollen-persistence/src/test/java/org/chorem/pollen/business/persistence/PollDAOImplTest.java trunk/pollen-services/src/main/java/org/chorem/pollen/services/PollenNotifierWorker.java trunk/pollen-services/src/main/java/org/chorem/pollen/services/impl/PollService.java trunk/pollen-services/src/main/java/org/chorem/pollen/services/impl/PreventRuleService.java Modified: trunk/pollen-persistence/src/main/java/org/chorem/pollen/business/persistence/PollDAOImpl.java =================================================================== --- trunk/pollen-persistence/src/main/java/org/chorem/pollen/business/persistence/PollDAOImpl.java 2012-12-01 12:28:56 UTC (rev 3760) +++ trunk/pollen-persistence/src/main/java/org/chorem/pollen/business/persistence/PollDAOImpl.java 2012-12-01 12:34:54 UTC (rev 3761) @@ -98,10 +98,10 @@ return result; } - public List<E> findRunningPolls(Date currentTime) throws TopiaException { + public List<E> findRunningPollsWithEndTime(Date currentTime) throws TopiaException { String hql = "FROM PollImpl WHERE " + - "(endDate IS NULL OR endDate > :currentTime) AND " + + "(endDate IS NOT NULL AND endDate > :currentTime) AND " + "(beginDate IS NULL OR beginDate < :currentTime)"; List<E> results = findAllByQuery(hql, "currentTime", currentTime); Modified: trunk/pollen-persistence/src/test/java/org/chorem/pollen/business/persistence/PollDAOImplTest.java =================================================================== --- trunk/pollen-persistence/src/test/java/org/chorem/pollen/business/persistence/PollDAOImplTest.java 2012-12-01 12:28:56 UTC (rev 3760) +++ trunk/pollen-persistence/src/test/java/org/chorem/pollen/business/persistence/PollDAOImplTest.java 2012-12-01 12:34:54 UTC (rev 3761) @@ -228,7 +228,7 @@ } @Test - public void findRunningPolls() throws Exception { + public void findRunningPollsWithEndTime() throws Exception { TopiaContext tx = beginTransaction(); PollDAO dao = PollenDAOHelper.getPollDAO(tx); @@ -257,36 +257,26 @@ List<Poll> actual; - actual = dao.findRunningPolls(now); + actual = dao.findRunningPollsWithEndTime(now); Assert.assertNotNull(actual); - Assert.assertEquals(5, actual.size()); - Assert.assertEquals(poll0, actual.get(0)); - Assert.assertEquals(poll1, actual.get(1)); - Assert.assertEquals(poll3, actual.get(2)); - Assert.assertEquals(poll4, actual.get(3)); - Assert.assertEquals(poll5, actual.get(4)); + Assert.assertEquals(3, actual.size()); + Assert.assertEquals(poll3, actual.get(0)); + Assert.assertEquals(poll4, actual.get(1)); + Assert.assertEquals(poll5, actual.get(2)); + actual = dao.findRunningPollsWithEndTime(lastYearNow); + Assert.assertNotNull(actual); + Assert.assertEquals(1, actual.size()); + Assert.assertEquals(poll5, actual.get(0)); - actual = dao.findRunningPolls(lastYearNow); + actual = dao.findRunningPollsWithEndTime(nextMonthNow); Assert.assertNotNull(actual); Assert.assertEquals(2, actual.size()); - Assert.assertEquals(poll0, actual.get(0)); + Assert.assertEquals(poll3, actual.get(0)); Assert.assertEquals(poll5, actual.get(1)); - actual = dao.findRunningPolls(nextMonthNow); + actual = dao.findRunningPollsWithEndTime(nextYearNow); Assert.assertNotNull(actual); - Assert.assertEquals(5, actual.size()); - Assert.assertEquals(poll0, actual.get(0)); - Assert.assertEquals(poll1, actual.get(1)); - Assert.assertEquals(poll2, actual.get(2)); - Assert.assertEquals(poll3, actual.get(3)); - Assert.assertEquals(poll5, actual.get(4)); - - actual = dao.findRunningPolls(nextYearNow); - Assert.assertNotNull(actual); - Assert.assertEquals(3, actual.size()); - Assert.assertEquals(poll0, actual.get(0)); - Assert.assertEquals(poll1, actual.get(1)); - Assert.assertEquals(poll2, actual.get(2)); + Assert.assertEquals(0, actual.size()); } } Modified: trunk/pollen-services/src/main/java/org/chorem/pollen/services/PollenNotifierWorker.java =================================================================== --- trunk/pollen-services/src/main/java/org/chorem/pollen/services/PollenNotifierWorker.java 2012-12-01 12:28:56 UTC (rev 3760) +++ trunk/pollen-services/src/main/java/org/chorem/pollen/services/PollenNotifierWorker.java 2012-12-01 12:34:54 UTC (rev 3761) @@ -23,6 +23,8 @@ package org.chorem.pollen.services; import com.google.common.base.Preconditions; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import org.chorem.pollen.PollenTechnicalException; import org.chorem.pollen.business.persistence.Poll; import org.chorem.pollen.business.persistence.PreventRule; @@ -47,6 +49,14 @@ */ public class PollenNotifierWorker implements Runnable, Closeable { + /** Logger. */ + private static final Log log = + LogFactory.getLog(PollenNotifierWorker.class); + + public static final int ONE_MINUTE = 60 * 1000; + + public static final int ONE_HOUR = 60 * ONE_MINUTE; + /** Service context used to create other services. */ protected final PollenServiceContext serviceContext; @@ -75,6 +85,9 @@ @Override public void run() { try { + if (log.isDebugEnabled()) { + log.debug("New round of " + PollenNotifierWorker.this); + } TopiaContext transaction = rootContext.beginTransaction(); try { serviceContext.setTransaction(transaction); @@ -84,14 +97,21 @@ PreventRuleService preventRuleService = serviceContext.newService(PreventRuleService.class); - // Récupération des sondages en cours - Date currentTime = serviceContext.getCurrentTime(); + // Get running polls with filled end date + Date now = serviceContext.getCurrentTime(); List<Poll> polls = - pollService.getRunningPolls(currentTime); + pollService.getRunningPollsWithEndTime(now); + if (log.isDebugEnabled()) { + log.debug("Found " + polls.size() + + " running polls with end date to scan"); + } for (Poll poll : polls) { - preventRuleService.onPollToRemind(poll); + if (log.isDebugEnabled()) { + log.debug("Tests for poll " + poll.getTitle()); + } + preventRuleService.onPollToRemind(poll, now); } @@ -105,7 +125,7 @@ throw new PollenTechnicalException("Topia problem", e); } } - }, 600000, 600000); + }, 0, 10 * ONE_MINUTE); // repeat at ten minutes } @Override Modified: trunk/pollen-services/src/main/java/org/chorem/pollen/services/impl/PollService.java =================================================================== --- trunk/pollen-services/src/main/java/org/chorem/pollen/services/impl/PollService.java 2012-12-01 12:28:56 UTC (rev 3760) +++ trunk/pollen-services/src/main/java/org/chorem/pollen/services/impl/PollService.java 2012-12-01 12:34:54 UTC (rev 3761) @@ -491,11 +491,11 @@ } } - public List<Poll> getRunningPolls(Date currentTime) { + public List<Poll> getRunningPollsWithEndTime(Date currentTime) { try { PollDAO dao = getDAO(Poll.class); - List<Poll> results = dao.findRunningPolls(currentTime); + List<Poll> results = dao.findRunningPollsWithEndTime(currentTime); return results; } catch (TopiaException e) { throw new PollenTechnicalException( @@ -1000,7 +1000,7 @@ } preventRuleLoaded.setMethod(preventRule.getMethod()); - preventRuleLoaded.setOneTime(preventRule.isOneTime()); +// preventRuleLoaded.setOneTime(preventRule.isOneTime()); preventRuleLoaded.setRepeated(preventRule.isRepeated()); preventRuleLoaded.setSensibility(preventRule.getSensibility()); } Modified: trunk/pollen-services/src/main/java/org/chorem/pollen/services/impl/PreventRuleService.java =================================================================== --- trunk/pollen-services/src/main/java/org/chorem/pollen/services/impl/PreventRuleService.java 2012-12-01 12:28:56 UTC (rev 3760) +++ trunk/pollen-services/src/main/java/org/chorem/pollen/services/impl/PreventRuleService.java 2012-12-01 12:34:54 UTC (rev 3761) @@ -27,6 +27,7 @@ import org.apache.commons.logging.LogFactory; import org.chorem.pollen.business.persistence.Poll; import org.chorem.pollen.business.persistence.PreventRule; +import org.chorem.pollen.services.PollenNotifierWorker; import org.chorem.pollen.services.PollenServiceSupport; import java.util.Date; @@ -67,112 +68,101 @@ if (poll.getEndDate() != null) { for (PreventRule rule : poll.getPreventRule()) { - onVoteAdded(poll, rule); - } - } - } - public void onPollToRemind(Poll poll) { + // send to creator a email to say hey a new vote was added! - // Parcours des preventRules de chaque sondage - // envoi d'un email si endDate-nowDate <= preventRuleSensibility - if (poll.getEndDate() != null) { + if (canExecuteRule(SCOPE_VOTE, rule, 1)) { - Date now = serviceContext.getCurrentTime(); + // ok can execute this task - // timeValue = endDate-nowDate - long timeValue = poll.getEndDate().getTime() - now.getTime(); + EmailService emailService = newService(EmailService.class); - if (log.isDebugEnabled()) { - log.debug("Now: " + now.getTime() + " End: " - + poll.getEndDate().getTime() + " timeValue: " - + timeValue + "(" + timeValue / 3600000 + "h)"); - } + // let's send an email + emailService.onVoteAdded(poll); - int hourBeforeEnd = (int) (timeValue / 3600000); - - for (PreventRule rule : poll.getPreventRule()) { - - onPollToRemind(poll, rule, hourBeforeEnd); + // and update prevent rule + commitTransaction("Could not update prevent rule"); + } } } } - protected void onVoteAdded(Poll poll, PreventRule preventRule) { + public void onPollToRemind(Poll poll, Date now) { - // send to creator a email to say hey a new vote was added! + Preconditions.checkNotNull(poll, "Poll can notbe nul."); - if (execute(SCOPE_VOTE, preventRule, 1)) { + Date endDate = poll.getEndDate(); + Preconditions.checkNotNull( + endDate, "End date can not be null to remind"); - // ok can execute this task + // envoi d'un email si endDate-nowDate <= preventRuleSensibility - EmailService emailService = newService(EmailService.class); + // timeValue = endDate-nowDate + long timeValue = endDate.getTime() - now.getTime(); - // let's send an email - emailService.onVoteAdded(poll); + int hourBeforeEnd = (int) (timeValue / PollenNotifierWorker.ONE_HOUR); - // and update prevent rule - commitTransaction("Could not update prevent rule"); + if (log.isDebugEnabled()) { + log.debug("Now: " + now.getTime() + " End: " + + endDate.getTime() + " timeValue: " + + timeValue + "(" + hourBeforeEnd + "h)"); } - } - protected void onPollToRemind(Poll poll, PreventRule preventRule, - int timeValue) { + for (PreventRule rule : poll.getPreventRule()) { - // send to all voting a email to say hey we need to vote + if (canExecuteRule(SCOPE_REMINDER, rule, hourBeforeEnd)) { - if (execute(SCOPE_REMINDER, preventRule, timeValue)) { + // ok can execute this task - // ok can execute this task + if (log.isInfoEnabled()) { + log.info("Execute reminder rule on poll " + poll.getTitle()); + } + EmailService emailService = newService(EmailService.class); - EmailService emailService = newService(EmailService.class); + // let's send an email + emailService.onPollReminder(poll); - // let's send an email - emailService.onPollReminder(poll); + // this rule must be desactivate now + rule.setActive(false); - // and update prevent rule - commitTransaction("Could not update prevent rule"); + // and update prevent rule + commitTransaction("Could not update prevent rule"); + } } } - protected boolean execute(String scope, PreventRule preventRule, - Integer value) { + protected boolean canExecuteRule(String scope, PreventRule preventRule, + Integer value) { Preconditions.checkNotNull(scope); Preconditions.checkNotNull(value); - // Si la règle n'est pas active, on ne fait rien - if (!preventRule.isActive()) { - log.debug("Règle non active"); - return false; - } + boolean result = false; - // Si la règle est à exécution unique, on la désactive - if (preventRule.isOneTime()) { - log.debug("Règle à exécution unique : désactivation"); - preventRule.setActive(false); - } + if (preventRule.isActive()) { - if (!scope.equals(preventRule.getScope())) { + // alive rule - // pas bon scope - return false; - } + if (scope.equals(preventRule.getScope())) { - // Si la règle est répétitive (exécution tous les n), on met à jour la valeur - if (preventRule.isRepeated() && preventRule.getSensibility() != 0) { - value = value % preventRule.getSensibility() - + preventRule.getSensibility(); - } + // rule in good scope - if (value != preventRule.getSensibility()) { + int sensibility = preventRule.getSensibility(); - // pas la bonne valeur - return false; + if (preventRule.isRepeated() && sensibility != 0) { + value = value % sensibility + sensibility; + } + + if (value == sensibility) { + + // ok good value, can execute this rule + result = true; + } + + } } - // ok on peut lancer la tâche - return true; + return result; } }