Skip to content

Commit

Permalink
[5999] Timeouts in session closing and closed reminders
Browse files Browse the repository at this point in the history
  • Loading branch information
wkurniawan07 authored Aug 19, 2016
1 parent 6d3ed47 commit 2a67b0a
Show file tree
Hide file tree
Showing 10 changed files with 265 additions and 81 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package teammates.client.scripts;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.jdo.PersistenceManager;
import javax.jdo.Query;

import teammates.client.remoteapi.RemoteApiClient;
import teammates.common.datatransfer.FeedbackSessionAttributes;
import teammates.common.datatransfer.FeedbackSessionType;
import teammates.common.util.Const.SystemParams;
import teammates.logic.api.Logic;
import teammates.storage.datastore.Datastore;
import teammates.storage.entity.FeedbackSession;

public class DataMigrationForSentClosingEmailFieldInSessions extends RemoteApiClient {

private static final Logic logic = new Logic();

private boolean isPreview = true;

public static void main(String[] args) throws IOException {
new DataMigrationForSentClosingEmailFieldInSessions().doOperationRemotely();
}

@Override
protected void doOperation() {
Datastore.initialize();

List<FeedbackSessionAttributes> sessions = getNonPrivateFeedbackSessions();
for (FeedbackSessionAttributes session : sessions) {
populateClosingEmailField(session);
}
}

private void populateClosingEmailField(FeedbackSessionAttributes session) {
session.setSentClosedEmail(session.isClosed());
session.setSentClosingEmail(
session.isClosed()
|| !session.isClosedAfter(SystemParams.NUMBER_OF_HOURS_BEFORE_CLOSING_ALERT));

if (isPreview) {
System.out.println("sentClosingEmail and sentClosedEmail for " + session.getSessionName()
+ " in course " + session.getCourseId() + " to be set to " + session.isClosed());
return;
}

try {
logic.updateFeedbackSession(session);
} catch (Exception e) {
System.out.println("Failed to set attribute sentClosingEmail and sentClosedEmail for session "
+ session.getSessionName() + " in course " + session.getCourseId() + ".");
e.printStackTrace();
}
}

private List<FeedbackSessionAttributes> getNonPrivateFeedbackSessions() {
List<FeedbackSessionAttributes> sessions = new ArrayList<FeedbackSessionAttributes>();
List<FeedbackSession> sessionEntities = getNonPrivateFeedbackSessionEntities();
for (FeedbackSession sessionEntity : sessionEntities) {
sessions.add(new FeedbackSessionAttributes(sessionEntity));
}
return sessions;
}

private PersistenceManager getPm() {
return Datastore.getPersistenceManager();
}

@SuppressWarnings("unchecked")
private List<FeedbackSession> getNonPrivateFeedbackSessionEntities() {
Query q = getPm().newQuery(FeedbackSession.class);
q.declareParameters("Enum private");
q.setFilter("feedbackSessionType != private");

return (List<FeedbackSession>) q.execute(FeedbackSessionType.PRIVATE);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ public class FeedbackSessionAttributes extends EntityAttributes implements Sessi
private int gracePeriod;
private FeedbackSessionType feedbackSessionType;
private boolean sentOpenEmail;
private boolean sentClosingEmail;
private boolean sentClosedEmail;
private boolean sentPublishedEmail;
private boolean isOpeningEmailEnabled;
private boolean isClosingEmailEnabled;
Expand Down Expand Up @@ -62,6 +64,8 @@ public FeedbackSessionAttributes(FeedbackSession fs) {
this.gracePeriod = fs.getGracePeriod();
this.feedbackSessionType = fs.getFeedbackSessionType();
this.sentOpenEmail = fs.isSentOpenEmail();
this.sentClosingEmail = fs.isSentClosingEmail();
this.sentClosedEmail = fs.isSentClosedEmail();
this.sentPublishedEmail = fs.isSentPublishedEmail();
this.isOpeningEmailEnabled = fs.isOpeningEmailEnabled();
this.isClosingEmailEnabled = fs.isClosingEmailEnabled();
Expand All @@ -76,20 +80,22 @@ public FeedbackSessionAttributes(String feedbackSessionName, String courseId, St
Text instructions, Date createdTime, Date startTime, Date endTime,
Date sessionVisibleFromTime, Date resultsVisibleFromTime,
double timeZone, int gracePeriod, FeedbackSessionType feedbackSessionType,
boolean sentOpenEmail, boolean sentPublishedEmail,
boolean sentOpenEmail, boolean sentClosingEmail,
boolean sentClosedEmail, boolean sentPublishedEmail,
boolean isOpeningEmailEnabled, boolean isClosingEmailEnabled,
boolean isPublishedEmailEnabled) {
this(feedbackSessionName, courseId, creatorId, instructions, createdTime, startTime, endTime,
sessionVisibleFromTime, resultsVisibleFromTime, timeZone, gracePeriod, feedbackSessionType,
sentOpenEmail, sentPublishedEmail, isOpeningEmailEnabled, isClosingEmailEnabled, isPublishedEmailEnabled,
new HashSet<String>(), new HashSet<String>());
sentOpenEmail, sentClosingEmail, sentClosedEmail, sentPublishedEmail, isOpeningEmailEnabled,
isClosingEmailEnabled, isPublishedEmailEnabled, new HashSet<String>(), new HashSet<String>());
}

public FeedbackSessionAttributes(String feedbackSessionName, String courseId, String creatorId,
Text instructions, Date createdTime, Date startTime, Date endTime,
Date sessionVisibleFromTime, Date resultsVisibleFromTime,
double timeZone, int gracePeriod, FeedbackSessionType feedbackSessionType,
boolean sentOpenEmail, boolean sentPublishedEmail,
boolean sentOpenEmail, boolean sentClosingEmail,
boolean sentClosedEmail, boolean sentPublishedEmail,
boolean isOpeningEmailEnabled, boolean isClosingEmailEnabled,
boolean isPublishedEmailEnabled, Set<String> instructorList,
Set<String> studentList) {
Expand All @@ -107,6 +113,8 @@ public FeedbackSessionAttributes(String feedbackSessionName, String courseId, St
this.gracePeriod = gracePeriod;
this.feedbackSessionType = feedbackSessionType;
this.sentOpenEmail = sentOpenEmail;
this.sentClosingEmail = sentClosingEmail;
this.sentClosedEmail = sentClosedEmail;
this.sentPublishedEmail = sentPublishedEmail;
this.isOpeningEmailEnabled = isOpeningEmailEnabled;
this.isClosingEmailEnabled = isClosingEmailEnabled;
Expand All @@ -120,7 +128,7 @@ private FeedbackSessionAttributes(FeedbackSessionAttributes other) {
other.instructions, other.createdTime, other.startTime, other.endTime,
other.sessionVisibleFromTime, other.resultsVisibleFromTime, other.timeZone,
other.gracePeriod, other.feedbackSessionType,
other.sentOpenEmail, other.sentPublishedEmail,
other.sentOpenEmail, other.sentClosingEmail, other.sentClosedEmail, other.sentPublishedEmail,
other.isOpeningEmailEnabled, other.isClosingEmailEnabled,
other.isPublishedEmailEnabled, other.respondingInstructorList,
other.respondingStudentList);
Expand Down Expand Up @@ -154,7 +162,8 @@ public String getInstructionsString() {
public FeedbackSession toEntity() {
return new FeedbackSession(feedbackSessionName, courseId, creatorEmail, instructions, createdTime,
startTime, endTime, sessionVisibleFromTime, resultsVisibleFromTime,
timeZone, gracePeriod, feedbackSessionType, sentOpenEmail, sentPublishedEmail,
timeZone, gracePeriod, feedbackSessionType, sentOpenEmail,
sentClosingEmail, sentClosedEmail, sentPublishedEmail,
isOpeningEmailEnabled, isClosingEmailEnabled, isPublishedEmailEnabled,
respondingInstructorList, respondingStudentList);
}
Expand Down Expand Up @@ -293,6 +302,24 @@ public boolean isValid() {
return getInvalidityInfo().isEmpty();
}

public boolean isClosedAfter(int hours) {
Calendar now = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
// Fix the time zone accordingly
now.add(Calendar.MILLISECOND, (int) (60 * 60 * 1000 * timeZone));

Calendar start = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
start.setTime(startTime);

Calendar deadline = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
deadline.setTime(endTime);

long nowMillis = now.getTimeInMillis();
long deadlineMillis = deadline.getTimeInMillis();
long differenceBetweenDeadlineAndNow = (deadlineMillis - nowMillis) / (60 * 60 * 1000);

return now.after(start) && differenceBetweenDeadlineAndNow < hours;
}

public boolean isClosingWithinTimeLimit(int hours) {
Calendar now = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
// Fix the time zone accordingly
Expand Down Expand Up @@ -641,6 +668,22 @@ public void setSentOpenEmail(boolean sentOpenEmail) {
this.sentOpenEmail = sentOpenEmail;
}

public boolean isSentClosingEmail() {
return sentClosingEmail;
}

public void setSentClosingEmail(boolean sentClosingEmail) {
this.sentClosingEmail = sentClosingEmail;
}

public boolean isSentClosedEmail() {
return sentClosedEmail;
}

public void setSentClosedEmail(boolean sentClosedEmail) {
this.sentClosedEmail = sentClosedEmail;
}

public boolean isSentPublishedEmail() {
return sentPublishedEmail;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
import javax.servlet.http.HttpServletRequest;

import teammates.common.datatransfer.FeedbackSessionAttributes;
import teammates.common.exception.EntityDoesNotExistException;
import teammates.common.exception.InvalidParametersException;
import teammates.common.util.Assumption;
import teammates.common.util.Const;
import teammates.common.util.Const.ParamsNames;
Expand Down Expand Up @@ -42,11 +44,11 @@ public FeedbackSessionClosedMailAction(HashMap<String, String> paramMap) {
}

@Override
protected void doPostProcessingForSuccesfulSend() {
/*
* Empty because no action is required on successful
* sending of feedback session closing mails
*/
protected void doPostProcessingForSuccesfulSend() throws InvalidParametersException, EntityDoesNotExistException {
FeedbackSessionAttributes feedbackObject = FeedbackSessionsLogic.inst()
.getFeedbackSession(feedbackSessionName, courseId);
feedbackObject.setSentClosedEmail(true);
FeedbackSessionsLogic.inst().updateFeedbackSession(feedbackObject);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
import javax.servlet.http.HttpServletRequest;

import teammates.common.datatransfer.FeedbackSessionAttributes;
import teammates.common.exception.EntityDoesNotExistException;
import teammates.common.exception.InvalidParametersException;
import teammates.common.util.Assumption;
import teammates.common.util.Const;
import teammates.common.util.Const.ParamsNames;
Expand Down Expand Up @@ -44,11 +46,11 @@ public FeedbackSessionClosingMailAction(HashMap<String, String> paramMap) {
}

@Override
protected void doPostProcessingForSuccesfulSend() {
/*
* Empty because no action is required on successful
* sending of feedback session closing mails
*/
protected void doPostProcessingForSuccesfulSend() throws InvalidParametersException, EntityDoesNotExistException {
FeedbackSessionAttributes feedbackObject = FeedbackSessionsLogic.inst()
.getFeedbackSession(feedbackSessionName, courseId);
feedbackObject.setSentClosingEmail(true);
FeedbackSessionsLogic.inst().updateFeedbackSession(feedbackObject);
}

@Override
Expand Down
45 changes: 25 additions & 20 deletions src/main/java/teammates/logic/core/FeedbackSessionsLogic.java
Original file line number Diff line number Diff line change
Expand Up @@ -1622,12 +1622,11 @@ public List<FeedbackSessionAttributes> getFeedbackSessionsClosingWithinTimeLimit
ArrayList<FeedbackSessionAttributes> requiredSessions = new
ArrayList<FeedbackSessionAttributes>();

List<FeedbackSessionAttributes> nonPrivateSessions = fsDb
.getNonPrivateFeedbackSessions();
List<FeedbackSessionAttributes> nonPrivateSessions =
fsDb.getFeedbackSessionsNeedingClosingEmail();

for (FeedbackSessionAttributes session : nonPrivateSessions) {
if (session.isClosingWithinTimeLimit(SystemParams.NUMBER_OF_HOURS_BEFORE_CLOSING_ALERT)
&& session.isClosingEmailEnabled()) {
if (session.isClosingWithinTimeLimit(SystemParams.NUMBER_OF_HOURS_BEFORE_CLOSING_ALERT)) {
requiredSessions.add(session);
}
}
Expand All @@ -1640,11 +1639,12 @@ public List<FeedbackSessionAttributes> getFeedbackSessionsClosingWithinTimeLimit
*/
public List<FeedbackSessionAttributes> getFeedbackSessionsClosedWithinThePastHour() {
List<FeedbackSessionAttributes> requiredSessions = new ArrayList<FeedbackSessionAttributes>();
List<FeedbackSessionAttributes> nonPrivateSessions = fsDb.getNonPrivateFeedbackSessions();
List<FeedbackSessionAttributes> nonPrivateSessions =
fsDb.getFeedbackSessionsNeedingClosedEmail();

for (FeedbackSessionAttributes session : nonPrivateSessions) {
if (session.isClosedWithinPastHour() // is session closed in the past 1 hour
&& session.isClosingEmailEnabled()) {
// is session closed in the past 1 hour
if (session.isClosedWithinPastHour()) {
requiredSessions.add(session);
}
}
Expand Down Expand Up @@ -2639,22 +2639,27 @@ private void normalizeMaximumResponseEntities(
private void makeEmailStateConsistent(FeedbackSessionAttributes oldSession,
FeedbackSessionAttributes newSession) {

// reset sentOpenEmail if the session has opened but is being closed
// now.
if (oldSession.isSentOpenEmail() && !newSession.isOpened()) {
newSession.setSentOpenEmail(false);
} else if (oldSession.isSentOpenEmail()) {
// or else leave it as sent if so.
newSession.setSentOpenEmail(true);
// reset sentOpenEmail if the session has opened but is being un-opened
// now, or else leave it as sent if so.
if (oldSession.isSentOpenEmail()) {
newSession.setSentOpenEmail(newSession.isOpened());
}

// reset sentClosedEmail if the session has closed but is being un-closed
// now, or else leave it as sent if so.
if (oldSession.isSentClosedEmail()) {
newSession.setSentClosedEmail(newSession.isClosed());

// also reset sentClosingEmail
newSession.setSentClosingEmail(
newSession.isClosed()
|| !newSession.isClosedAfter(SystemParams.NUMBER_OF_HOURS_BEFORE_CLOSING_ALERT));
}

// reset sentPublishedEmail if the session has been published but is
// going to be unpublished now.
if (oldSession.isSentPublishedEmail() && !newSession.isPublished()) {
newSession.setSentPublishedEmail(false);
} else if (oldSession.isSentPublishedEmail()) {
// or else leave it as sent if so.
newSession.setSentPublishedEmail(true);
// going to be unpublished now, or else leave it as sent if so.
if (oldSession.isSentPublishedEmail()) {
newSession.setSentPublishedEmail(newSession.isPublished());
}
}

Expand Down
Loading

0 comments on commit 2a67b0a

Please sign in to comment.