diff --git a/SingularityService/src/main/java/com/hubspot/singularity/config/SMTPConfiguration.java b/SingularityService/src/main/java/com/hubspot/singularity/config/SMTPConfiguration.java index 4bccd57bff..0861e9a814 100644 --- a/SingularityService/src/main/java/com/hubspot/singularity/config/SMTPConfiguration.java +++ b/SingularityService/src/main/java/com/hubspot/singularity/config/SMTPConfiguration.java @@ -1,8 +1,9 @@ package com.hubspot.singularity.config; +import java.util.List; +import java.util.TimeZone; import java.util.Arrays; import java.util.Collections; -import java.util.List; import java.util.Map; import java.util.concurrent.TimeUnit; @@ -38,6 +39,9 @@ public class SMTPConfiguration { @NotNull private String from = "singularity-no-reply@example.com"; + @JsonProperty + private String mailerDatePattern = "MMM dd h:mm:ss a zzz"; + @JsonProperty private int mailMaxThreads = 3; @@ -66,6 +70,9 @@ public class SMTPConfiguration { @JsonProperty private List taskEmailTailFiles = Arrays.asList("stdout", "stderr"); + @JsonProperty + private TimeZone mailerTimeZone = TimeZone.getTimeZone("UTC"); + @JsonProperty("emails") private Map> emailConfiguration = Maps.newHashMap(ImmutableMap.>builder() .put(SingularityEmailType.REQUEST_IN_COOLDOWN, ImmutableList.of(SingularityEmailDestination.ADMINS, SingularityEmailDestination.OWNERS)) @@ -201,4 +208,20 @@ public List getTaskEmailTailFiles() { public void setTaskEmailTailFiles(List taskEmailTailFiles) { this.taskEmailTailFiles = taskEmailTailFiles; } + + public String getMailerDatePattern() { + return mailerDatePattern; + } + + public void setMailerDatePattern(String mailerDatePattern) { + this.mailerDatePattern = mailerDatePattern; + } + + public TimeZone getMailerTimeZone() { + return mailerTimeZone; + } + + public void setMailerTimeZone(TimeZone mailerTimeZone) { + this.mailerTimeZone = mailerTimeZone; + } } diff --git a/SingularityService/src/main/java/com/hubspot/singularity/config/SingularityConfiguration.java b/SingularityService/src/main/java/com/hubspot/singularity/config/SingularityConfiguration.java index 09457c8274..80bcc3033a 100644 --- a/SingularityService/src/main/java/com/hubspot/singularity/config/SingularityConfiguration.java +++ b/SingularityService/src/main/java/com/hubspot/singularity/config/SingularityConfiguration.java @@ -4,6 +4,7 @@ import java.util.List; import java.util.Map; import java.util.concurrent.TimeUnit; +import java.util.TimeZone; import javax.validation.Valid; import javax.validation.constraints.Max; diff --git a/SingularityService/src/main/java/com/hubspot/singularity/smtp/MailTemplateHelpers.java b/SingularityService/src/main/java/com/hubspot/singularity/smtp/MailTemplateHelpers.java index 3abb518e05..c9e3202d79 100644 --- a/SingularityService/src/main/java/com/hubspot/singularity/smtp/MailTemplateHelpers.java +++ b/SingularityService/src/main/java/com/hubspot/singularity/smtp/MailTemplateHelpers.java @@ -3,6 +3,7 @@ import java.util.Collection; import java.util.Collections; import java.util.List; +import java.util.TimeZone; import org.apache.commons.lang3.text.WordUtils; import org.apache.commons.lang3.time.DateFormatUtils; @@ -29,30 +30,49 @@ public class MailTemplateHelpers { private static final Logger LOG = LoggerFactory.getLogger(MailTemplateHelpers.class); - private static final String TASK_DATE_PATTERN = "MMM dd HH:mm:ss"; private static final String TASK_LINK_FORMAT = "%s/task/%s"; private static final String REQUEST_LINK_FORMAT = "%s/request/%s"; private static final String LOG_LINK_FORMAT = "%s/task/%s/tail/%s"; + private static final String DEFAULT_TIMESTAMP_FORMAT = "MMM dd h:mm:ss a zzz"; private final SandboxManager sandboxManager; private final Optional uiBaseUrl; private final Optional smtpConfiguration; + private final Optional taskDatePattern; + private final Optional timeZone; @Inject public MailTemplateHelpers(SandboxManager sandboxManager, SingularityConfiguration singularityConfiguration) { this.uiBaseUrl = singularityConfiguration.getUiConfiguration().getBaseUrl(); this.sandboxManager = sandboxManager; this.smtpConfiguration = singularityConfiguration.getSmtpConfiguration(); + if (this.smtpConfiguration.isPresent()) { + this.taskDatePattern = Optional.of(this.smtpConfiguration.get().getMailerDatePattern()); + this.timeZone = Optional.of(this.smtpConfiguration.get().getMailerTimeZone()); + } else { + this.taskDatePattern = Optional.absent(); + this.timeZone = Optional.absent(); + } } public List getJadeTaskHistory(Collection taskHistory) { List output = Lists.newArrayListWithCapacity(taskHistory.size()); for (SingularityTaskHistoryUpdate taskUpdate : taskHistory) { + String date; + if (taskDatePattern.isPresent() && timeZone.isPresent()) { + date = DateFormatUtils.format(taskUpdate.getTimestamp(), taskDatePattern.get(), timeZone.get()); + } else if (taskDatePattern.isPresent()) { + date = DateFormatUtils.formatUTC(taskUpdate.getTimestamp(), taskDatePattern.get()); + } else if (timeZone.isPresent()) { + date = DateFormatUtils.format(taskUpdate.getTimestamp(), DEFAULT_TIMESTAMP_FORMAT, timeZone.get()); + } else { + date = DateFormatUtils.format(taskUpdate.getTimestamp(), DEFAULT_TIMESTAMP_FORMAT); + } output.add( new SingularityMailTaskHistoryUpdate( - DateFormatUtils.formatUTC(taskUpdate.getTimestamp(), TASK_DATE_PATTERN), + date, WordUtils.capitalize(taskUpdate.getTaskState().getDisplayName()), taskUpdate.getStatusMessage().or(""))); } diff --git a/SingularityService/src/main/java/com/hubspot/singularity/smtp/SingularityMailer.java b/SingularityService/src/main/java/com/hubspot/singularity/smtp/SingularityMailer.java index 48e3313cc3..a30d683f22 100644 --- a/SingularityService/src/main/java/com/hubspot/singularity/smtp/SingularityMailer.java +++ b/SingularityService/src/main/java/com/hubspot/singularity/smtp/SingularityMailer.java @@ -12,6 +12,7 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; +import org.apache.commons.lang3.time.DateFormatUtils; import org.apache.commons.lang3.time.DurationFormatUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -399,8 +400,10 @@ private void setupExpireFormat(Map additionalProperties, Optiona final long now = System.currentTimeMillis(); final long future = now + durationMillis.get(); - - additionalProperties.put("expireFormat", new Date(future)); + if (maybeSmtpConfiguration.isPresent()) { + SMTPConfiguration smtpConfiguration = maybeSmtpConfiguration.get(); + additionalProperties.put("expireFormat", DateFormatUtils.format(new Date(future), smtpConfiguration.getMailerDatePattern(), smtpConfiguration.getMailerTimeZone())); + } } public void sendRequestPausedMail(SingularityRequest request, Optional pauseRequest, Optional user) { diff --git a/SingularityService/src/main/resources/templates/request_modified.jade b/SingularityService/src/main/resources/templates/request_modified.jade index 82290b24cf..1011d6805a 100644 --- a/SingularityService/src/main/resources/templates/request_modified.jade +++ b/SingularityService/src/main/resources/templates/request_modified.jade @@ -43,9 +43,9 @@ html else | #{ requestId } will not run again until it is manually unpaused. if killTasks - | Existing tasks will be killed. + | Existing tasks will be killed. else - | Existing tasks will not be killed. + | Existing tasks will not be killed. else if requestUnpaused | #{ requestId } will begin scheduling and executing tasks immediately. else if requestScaled