summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjørn Christian Seime <bjorn.christian@seime.no>2023-10-30 12:40:17 +0100
committerGitHub <noreply@github.com>2023-10-30 12:40:17 +0100
commit70cf1f41940b73b7db3cc219e6119030e094cf3f (patch)
tree2e574378490dc8c4a2fa9691c585cc3cd21236c5
parent8c7f1f8febf12a5b8468819ba9ff1ede014143d1 (diff)
parent14cfb5a6e86846fd156367673379e819dd6a28d2 (diff)
Merge pull request #29151 from vespa-engine/bjorncs/email-notification
Move trial notification emails to separate templates
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/CloudTrialExpirer.java43
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/notification/MailTemplating.java4
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/TrialNotifications.java2
-rw-r--r--controller-server/src/main/resources/mail/cloud-trial-notification.vm3
-rw-r--r--controller-server/src/main/resources/mail/trial-expired.vm3
-rw-r--r--controller-server/src/main/resources/mail/trial-expires-immediately.vm3
-rw-r--r--controller-server/src/main/resources/mail/trial-midway-checkin.vm3
-rw-r--r--controller-server/src/main/resources/mail/trial-signed-up.vm3
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/CloudTrialExpirerTest.java50
-rw-r--r--controller-server/src/test/resources/mail/trial-expires-immediately.html (renamed from controller-server/src/test/resources/mail/trial-expiring-immediately.html)0
-rw-r--r--controller-server/src/test/resources/mail/trial-expiring-soon.html646
-rw-r--r--controller-server/src/test/resources/mail/trial-midway-checkin.html (renamed from controller-server/src/test/resources/mail/trial-reminder.html)0
-rw-r--r--controller-server/src/test/resources/mail/trial-signed-up.html (renamed from controller-server/src/test/resources/mail/welcome.html)0
13 files changed, 56 insertions, 704 deletions
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/CloudTrialExpirer.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/CloudTrialExpirer.java
index 55428e80493..1e261f78db3 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/CloudTrialExpirer.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/CloudTrialExpirer.java
@@ -30,7 +30,6 @@ import java.util.stream.Collectors;
import static com.yahoo.vespa.hosted.controller.persistence.TrialNotifications.State.EXPIRED;
import static com.yahoo.vespa.hosted.controller.persistence.TrialNotifications.State.EXPIRES_IMMEDIATELY;
-import static com.yahoo.vespa.hosted.controller.persistence.TrialNotifications.State.EXPIRES_SOON;
import static com.yahoo.vespa.hosted.controller.persistence.TrialNotifications.State.MID_CHECK_IN;
import static com.yahoo.vespa.hosted.controller.persistence.TrialNotifications.State.SIGNED_UP;
import static com.yahoo.vespa.hosted.controller.persistence.TrialNotifications.State.UNKNOWN;
@@ -95,6 +94,14 @@ public class CloudTrialExpirer extends ControllerMaintainer {
return tombstoneTenants(idleOldPlanTenants);
}
+
+ /*
+ * Trial plan notification states. Transition to a new state triggers a notification/email
+ * - SIGNED_UP: Tenant has signed up for trial
+ * - MID_CHECK_IN: Tenant is halfway through trial (7 days)
+ * - EXPIRES_IMMEDIATELY: Tenant has 1 day left of trial
+ * - EXPIRED: Tenant has expired
+ */
private boolean notifyTenants() {
try {
var currentStatus = controller().curator().readTrialNotifications()
@@ -129,12 +136,8 @@ public class CloudTrialExpirer extends ControllerMaintainer {
&& !List.of(EXPIRES_IMMEDIATELY, EXPIRED).contains(state)) {
updatedStatus.add(updatedStatus(tenant, now, EXPIRES_IMMEDIATELY));
notifyExpiresImmediately(tenant);
- } else if ("trial".equals(plan) && ageInDays >= 12
- && !List.of(EXPIRES_SOON, EXPIRES_IMMEDIATELY, EXPIRED).contains(state)) {
- updatedStatus.add(updatedStatus(tenant, now, EXPIRES_SOON));
- notifyExpiresSoon(tenant);
} else if ("trial".equals(plan) && ageInDays >= 7
- && !List.of(MID_CHECK_IN, EXPIRES_SOON, EXPIRES_IMMEDIATELY, EXPIRED).contains(state)) {
+ && !List.of(MID_CHECK_IN, EXPIRES_IMMEDIATELY, EXPIRED).contains(state)) {
updatedStatus.add(updatedStatus(tenant, now, MID_CHECK_IN));
notifyMidCheckIn(tenant);
} else {
@@ -152,44 +155,28 @@ public class CloudTrialExpirer extends ControllerMaintainer {
private void notifySignup(Tenant tenant) {
var consoleMsg = "Welcome to Vespa Cloud trial! [Manage plan](%s)".formatted(billingUrl(tenant));
- queueNotification(tenant, consoleMsg, "Welcome to Vespa Cloud",
- "Welcome to Vespa Cloud! We hope you will enjoy your trial. " +
- "Please reach out to us if you have any questions or feedback.");
+ queueNotification(tenant, consoleMsg, "Welcome to Vespa Cloud", MailTemplating.Template.TRIAL_SIGNED_UP);
}
private void notifyMidCheckIn(Tenant tenant) {
var consoleMsg = "You're halfway through the **14 day** trial period. [Manage plan](%s)".formatted(billingUrl(tenant));
- queueNotification(tenant, consoleMsg, "How is your Vespa Cloud trial going?",
- "How is your Vespa Cloud trial going? " +
- "Please reach out to us if you have any questions or feedback.");
- }
-
- private void notifyExpiresSoon(Tenant tenant) {
- var consoleMsg = "Your Vespa Cloud trial expires in **2** days. [Manage plan](%s)".formatted(billingUrl(tenant));
- queueNotification(tenant, consoleMsg, "Your Vespa Cloud trial expires in 2 days",
- "Your Vespa Cloud trial expires in 2 days. " +
- "Please reach out to us if you have any questions or feedback.");
+ queueNotification(tenant, consoleMsg, "How is your Vespa Cloud trial going?", MailTemplating.Template.TRIAL_MIDWAY_CHECKIN);
}
private void notifyExpiresImmediately(Tenant tenant) {
var consoleMsg = "Your Vespa Cloud trial expires **tomorrow**. [Manage plan](%s)".formatted(billingUrl(tenant));
- queueNotification(tenant, consoleMsg, "Your Vespa Cloud trial expires tomorrow",
- "Your Vespa Cloud trial expires tomorrow. " +
- "Please reach out to us if you have any questions or feedback.");
+ queueNotification(tenant, consoleMsg, "Your Vespa Cloud trial expires tomorrow", MailTemplating.Template.TRIAL_EXPIRES_IMMEDIATELY);
}
private void notifyExpired(Tenant tenant) {
var consoleMsg = "Your Vespa Cloud trial has expired. [Upgrade plan](%s)".formatted(billingUrl(tenant));
- queueNotification(tenant, consoleMsg, "Your Vespa Cloud trial has expired",
- "Your Vespa Cloud trial has expired. " +
- "Please reach out to us if you have any questions or feedback.");
+ queueNotification(tenant, consoleMsg, "Your Vespa Cloud trial has expired", MailTemplating.Template.TRIAL_EXPIRED);
}
- private void queueNotification(Tenant tenant, String consoleMsg, String emailSubject, String emailMsg) {
+ private void queueNotification(Tenant tenant, String consoleMsg, String emailSubject, MailTemplating.Template template) {
var mail = Optional.of(Notification.MailContent.fromTemplate(MailTemplating.Template.DEFAULT_MAIL_CONTENT)
.subject(emailSubject)
- .with("mailMessageTemplate", "cloud-trial-notification")
- .with("cloudTrialMessage", emailMsg)
+ .with("mailMessageTemplate", template.getId())
.with("mailTitle", emailSubject)
.with("consoleLink", controller().serviceRegistry().consoleUrls().tenantOverview(tenant.name()))
.build());
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/notification/MailTemplating.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/notification/MailTemplating.java
index 1c05330702e..642840bf2b3 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/notification/MailTemplating.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/notification/MailTemplating.java
@@ -25,7 +25,9 @@ public class MailTemplating {
public enum Template {
MAIL("mail"), DEFAULT_MAIL_CONTENT("default-mail-content"), NOTIFICATION_MESSAGE("notification-message"),
- CLOUD_TRIAL_NOTIFICATION("cloud-trial-notification"), MAIL_VERIFICATION("mail-verification");
+ MAIL_VERIFICATION("mail-verification"), TRIAL_SIGNED_UP("trial-signed-up"), TRIAL_MIDWAY_CHECKIN("trial-midway-checkin"),
+ TRIAL_EXPIRES_IMMEDIATELY("trial-expires-immediately"), TRIAL_EXPIRED("trial-expired")
+ ;
public static Optional<Template> fromId(String id) {
return Arrays.stream(values()).filter(t -> t.id.equals(id)).findAny();
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/TrialNotifications.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/TrialNotifications.java
index a205e6c4173..cf6923b1e2c 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/TrialNotifications.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/TrialNotifications.java
@@ -21,7 +21,7 @@ public record TrialNotifications(List<Status> tenants) {
public TrialNotifications { tenants = List.copyOf(tenants); }
public record Status(TenantName tenant, State state, Instant lastUpdate) {}
- public enum State { SIGNED_UP, MID_CHECK_IN, EXPIRES_SOON, EXPIRES_IMMEDIATELY, EXPIRED, UNKNOWN }
+ public enum State { SIGNED_UP, MID_CHECK_IN, EXPIRES_IMMEDIATELY, EXPIRED, UNKNOWN }
public Slime toSlime() {
var slime = new Slime();
diff --git a/controller-server/src/main/resources/mail/cloud-trial-notification.vm b/controller-server/src/main/resources/mail/cloud-trial-notification.vm
deleted file mode 100644
index c1ba394bf8e..00000000000
--- a/controller-server/src/main/resources/mail/cloud-trial-notification.vm
+++ /dev/null
@@ -1,3 +0,0 @@
-<p>
- $esc.html($cloudTrialMessage)
-</p> \ No newline at end of file
diff --git a/controller-server/src/main/resources/mail/trial-expired.vm b/controller-server/src/main/resources/mail/trial-expired.vm
new file mode 100644
index 00000000000..02d2aacd117
--- /dev/null
+++ b/controller-server/src/main/resources/mail/trial-expired.vm
@@ -0,0 +1,3 @@
+<p>
+ Your Vespa Cloud trial has expired. Please reach out to us if you have any questions or feedback.
+</p> \ No newline at end of file
diff --git a/controller-server/src/main/resources/mail/trial-expires-immediately.vm b/controller-server/src/main/resources/mail/trial-expires-immediately.vm
new file mode 100644
index 00000000000..79604cae2e5
--- /dev/null
+++ b/controller-server/src/main/resources/mail/trial-expires-immediately.vm
@@ -0,0 +1,3 @@
+<p>
+ Your Vespa Cloud trial expires tomorrow. Please reach out to us if you have any questions or feedback.
+</p> \ No newline at end of file
diff --git a/controller-server/src/main/resources/mail/trial-midway-checkin.vm b/controller-server/src/main/resources/mail/trial-midway-checkin.vm
new file mode 100644
index 00000000000..c29c2763ef1
--- /dev/null
+++ b/controller-server/src/main/resources/mail/trial-midway-checkin.vm
@@ -0,0 +1,3 @@
+<p>
+ How is your Vespa Cloud trial going? Please reach out to us if you have any questions or feedback.
+</p> \ No newline at end of file
diff --git a/controller-server/src/main/resources/mail/trial-signed-up.vm b/controller-server/src/main/resources/mail/trial-signed-up.vm
new file mode 100644
index 00000000000..20f1867b7bc
--- /dev/null
+++ b/controller-server/src/main/resources/mail/trial-signed-up.vm
@@ -0,0 +1,3 @@
+<p>
+ Welcome to Vespa Cloud! We hope you will enjoy your trial. Please reach out to us if you have any questions or feedback.
+</p> \ No newline at end of file
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/CloudTrialExpirerTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/CloudTrialExpirerTest.java
index 4056459c532..02d0a020cd2 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/CloudTrialExpirerTest.java
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/CloudTrialExpirerTest.java
@@ -110,40 +110,41 @@ public class CloudTrialExpirerTest {
.withBooleanFlag(Flags.CLOUD_TRIAL_NOTIFICATIONS.id(), true);
registerTenant(tenant.value(), "trial", Duration.ZERO);
assertEquals(0.0, expirer.maintain());
- var expected = "Welcome to Vespa Cloud trial! [Manage plan](https://console.tld/tenant/trial-tenant/account/billing)";
- assertEquals(expected, lastAccountLevelNotificationTitle(tenant));
- assertLastEmailEquals(mailer, "welcome.html");
-
- expected = "You're halfway through the **14 day** trial period. [Manage plan](https://console.tld/tenant/trial-tenant/account/billing)";
+ var expectedConsoleNotification =
+ "Welcome to Vespa Cloud trial! [Manage plan](https://console.tld/tenant/trial-tenant/account/billing)";
+ var notification = lastAccountLevelNotification(tenant);
+ assertEquals(expectedConsoleNotification, notification.title());
+ assertLastEmail(mailer, notification);
+
+ expectedConsoleNotification =
+ "You're halfway through the **14 day** trial period. [Manage plan](https://console.tld/tenant/trial-tenant/account/billing)";
clock.advance(Duration.ofDays(7));
assertEquals(0.0, expirer.maintain());
- assertEquals(expected, lastAccountLevelNotificationTitle(tenant));
- assertLastEmailEquals(mailer, "trial-reminder.html");
-
- expected = "Your Vespa Cloud trial expires in **2** days. [Manage plan](https://console.tld/tenant/trial-tenant/account/billing)";
- clock.advance(Duration.ofDays(5));
- assertEquals(0.0, expirer.maintain());
- assertEquals(expected, lastAccountLevelNotificationTitle(tenant));
- assertLastEmailEquals(mailer, "trial-expiring-soon.html");
+ notification = lastAccountLevelNotification(tenant);
+ assertEquals(expectedConsoleNotification, notification.title());
+ assertLastEmail(mailer, notification);
- expected = "Your Vespa Cloud trial expires **tomorrow**. [Manage plan](https://console.tld/tenant/trial-tenant/account/billing)";
- clock.advance(Duration.ofDays(1));
+ expectedConsoleNotification = "Your Vespa Cloud trial expires **tomorrow**. [Manage plan](https://console.tld/tenant/trial-tenant/account/billing)";
+ clock.advance(Duration.ofDays(6));
assertEquals(0.0, expirer.maintain());
- assertEquals(expected, lastAccountLevelNotificationTitle(tenant));
- assertLastEmailEquals(mailer, "trial-expiring-immediately.html");
+ notification = lastAccountLevelNotification(tenant);
+ assertEquals(expectedConsoleNotification, notification.title());
+ assertLastEmail(mailer, notification);
- expected = "Your Vespa Cloud trial has expired. [Upgrade plan](https://console.tld/tenant/trial-tenant/account/billing)";
+ expectedConsoleNotification = "Your Vespa Cloud trial has expired. [Upgrade plan](https://console.tld/tenant/trial-tenant/account/billing)";
clock.advance(Duration.ofDays(2));
assertEquals(0.0, expirer.maintain());
- assertEquals(expected, lastAccountLevelNotificationTitle(tenant));
- assertLastEmailEquals(mailer, "trial-expired.html");
+ notification = lastAccountLevelNotification(tenant);
+ assertEquals(expectedConsoleNotification, notification.title());
+ assertLastEmail(mailer, notification);
}
- private void assertLastEmailEquals(MockMailer mailer, String expectedContentFile) throws IOException {
+ private void assertLastEmail(MockMailer mailer, Notification notification) throws IOException {
var mails = mailer.inbox("dev-trial-tenant");
assertFalse(mails.isEmpty());
var content = mails.get(mails.size() - 1).htmlMessage().orElseThrow();
- var path = Paths.get("src/test/resources/mail/" + expectedContentFile);
+ var templateName = notification.mailContent().orElseThrow().values().get("mailMessageTemplate");
+ var path = Paths.get("src/test/resources/mail/%s.html".formatted(templateName));
if (OVERWRITE_TEST_FILES) {
Files.write(path, content.getBytes(),
StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING, StandardOpenOption.WRITE);
@@ -175,11 +176,10 @@ public class CloudTrialExpirerTest {
assertEquals(planId, tester.serviceRegistry().billingController().getPlan(TenantName.from(tenant)).value());
}
- private String lastAccountLevelNotificationTitle(TenantName tenant) {
+ private Notification lastAccountLevelNotification(TenantName tenant) {
return tester.controller().notificationsDb()
.listNotifications(NotificationSource.from(tenant), false).stream()
- .filter(n -> n.type() == Notification.Type.account).map(Notification::title)
+ .filter(n -> n.type() == Notification.Type.account)
.findFirst().orElseThrow();
}
-
}
diff --git a/controller-server/src/test/resources/mail/trial-expiring-immediately.html b/controller-server/src/test/resources/mail/trial-expires-immediately.html
index db89eca195a..db89eca195a 100644
--- a/controller-server/src/test/resources/mail/trial-expiring-immediately.html
+++ b/controller-server/src/test/resources/mail/trial-expires-immediately.html
diff --git a/controller-server/src/test/resources/mail/trial-expiring-soon.html b/controller-server/src/test/resources/mail/trial-expiring-soon.html
deleted file mode 100644
index 17c59240cc4..00000000000
--- a/controller-server/src/test/resources/mail/trial-expiring-soon.html
+++ /dev/null
@@ -1,646 +0,0 @@
-<!DOCTYPE html>
-<html
- xmlns="http://www.w3.org/1999/xhtml"
- xmlns:v="urn:schemas-microsoft-com:vml"
- xmlns:o="urn:schemas-microsoft-com:office:office"
->
- <head>
- <title></title>
- <!--[if !mso]><!-->
- <meta http-equiv="X-UA-Compatible" content="IE=edge" />
- <!--<![endif]-->
- <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
- <meta name="viewport" content="width=device-width,initial-scale=1" />
- <style type="text/css">
- #outlook a {
- padding: 0;
- }
-
- body {
- margin: 0;
- padding: 0;
- -webkit-text-size-adjust: 100%;
- -ms-text-size-adjust: 100%;
- }
-
- table,
- td {
- border-collapse: collapse;
- mso-table-lspace: 0pt;
- mso-table-rspace: 0pt;
- }
-
- img {
- border: 0;
- height: auto;
- line-height: 100%;
- outline: none;
- text-decoration: none;
- -ms-interpolation-mode: bicubic;
- }
-
- p {
- display: block;
- margin: 13px 0;
- }
- </style>
- <!--[if mso]>
- <noscript>
- <xml>
- <o:OfficeDocumentSettings>
- <o:AllowPNG />
- <o:PixelsPerInch>96</o:PixelsPerInch>
- </o:OfficeDocumentSettings>
- </xml>
- </noscript>
- <![endif]-->
- <!--[if lte mso 11]>
- <style type="text/css">
- .mj-outlook-group-fix {
- width: 100% !important;
- }
- </style>
- <![endif]-->
- <!--[if !mso]><!-->
- <link
- href="https://fonts.googleapis.com/css?family=Open Sans"
- rel="stylesheet"
- type="text/css"
- />
- <style type="text/css">
- @import url(https://fonts.googleapis.com/css?family=Open Sans);
- </style>
- <!--<![endif]-->
- <style type="text/css">
- @media only screen and (min-width: 480px) {
- .mj-column-per-100 {
- width: 100% !important;
- max-width: 100%;
- }
- }
- </style>
- <style media="screen and (min-width:480px)">
- .moz-text-html .mj-column-per-100 {
- width: 100% !important;
- max-width: 100%;
- }
- </style>
- <style type="text/css">
- [owa] .mj-column-per-100 {
- width: 100% !important;
- max-width: 100%;
- }
- </style>
- <style type="text/css">
- @media only screen and (max-width: 480px) {
- table.mj-full-width-mobile {
- width: 100% !important;
- }
-
- td.mj-full-width-mobile {
- width: auto !important;
- }
- }
- </style>
- </head>
-
- <body style="word-spacing: normal; background-color: #f2f7fa">
- <div style="background-color: #f2f7fa">
- <!--[if mso | IE]><table align="center" border="0" cellpadding="0" cellspacing="0" class="" role="presentation" style="width:600px;" width="600" ><tr><td style="line-height:0px;font-size:0px;mso-line-height-rule:exactly;"><![endif]-->
- <div style="margin: 0px auto; max-width: 600px">
- <table
- align="center"
- border="0"
- cellpadding="0"
- cellspacing="0"
- role="presentation"
- style="width: 100%"
- >
- <tbody>
- <tr>
- <td
- style="
- direction: ltr;
- font-size: 0px;
- padding: 20px 0px 20px 0px;
- padding-bottom: 0px;
- padding-top: 0px;
- text-align: center;
- "
- >
- <!--[if mso | IE]><table role="presentation" border="0" cellpadding="0" cellspacing="0"><tr><td class="" style="vertical-align:top;width:600px;" ><![endif]-->
- <div
- class="mj-column-per-100 mj-outlook-group-fix"
- style="
- font-size: 0px;
- text-align: left;
- direction: ltr;
- display: inline-block;
- vertical-align: top;
- width: 100%;
- "
- >
- <table
- border="0"
- cellpadding="0"
- cellspacing="0"
- role="presentation"
- style="vertical-align: top"
- width="100%"
- >
- <tbody>
- <tr>
- <td
- align="left"
- style="
- font-size: 0px;
- padding: 0px 0px 0px 25px;
- padding-top: 0px;
- padding-bottom: 0px;
- word-break: break-word;
- "
- >
- <div
- style="
- font-family: Open Sans, Helvetica, Arial,
- sans-serif;
- font-size: 11px;
- line-height: 22px;
- text-align: left;
- color: #797e82;
- "
- >
- <br />
- </div>
- </td>
- </tr>
- </tbody>
- </table>
- </div>
- <!--[if mso | IE]></td></tr></table><![endif]-->
- </td>
- </tr>
- </tbody>
- </table>
- </div>
- <!--[if mso | IE]></td></tr></table><table align="center" border="0" cellpadding="0" cellspacing="0" class="" role="presentation" style="width:600px;" width="600" bgcolor="#ffffff" ><tr><td style="line-height:0px;font-size:0px;mso-line-height-rule:exactly;"><![endif]-->
- <div
- style="
- background: #ffffff;
- background-color: #ffffff;
- margin: 0px auto;
- max-width: 600px;
- "
- >
- <table
- align="center"
- border="0"
- cellpadding="0"
- cellspacing="0"
- role="presentation"
- style="background: #ffffff; background-color: #ffffff; width: 100%"
- >
- <tbody>
- <tr>
- <td
- style="
- direction: ltr;
- font-size: 0px;
- padding: 20px 0;
- padding-bottom: 0px;
- padding-left: 0px;
- padding-right: 0px;
- padding-top: 0px;
- text-align: center;
- "
- >
- <!--[if mso | IE]><table role="presentation" border="0" cellpadding="0" cellspacing="0"><tr><td class="" style="vertical-align:top;width:600px;" ><![endif]-->
- <div
- class="mj-column-per-100 mj-outlook-group-fix"
- style="
- font-size: 0px;
- text-align: left;
- direction: ltr;
- display: inline-block;
- vertical-align: top;
- width: 100%;
- "
- >
- <table
- border="0"
- cellpadding="0"
- cellspacing="0"
- role="presentation"
- style="vertical-align: top"
- width="100%"
- >
- <tbody>
- <tr>
- <td
- align="center"
- style="
- font-size: 0px;
- padding: 10px 25px;
- padding-top: 0px;
- padding-right: 0px;
- padding-bottom: 40px;
- padding-left: 0px;
- word-break: break-word;
- "
- >
- <p
- style="
- border-top: solid 8px #005a8e;
- font-size: 1px;
- margin: 0px auto;
- width: 100%;
- "
- ></p>
- <!--[if mso | IE
- ]><table
- align="center"
- border="0"
- cellpadding="0"
- cellspacing="0"
- style="
- border-top: solid 8px #005a8e;
- font-size: 1px;
- margin: 0px auto;
- width: 600px;
- "
- role="presentation"
- width="600px"
- >
- <tr>
- <td style="height: 0; line-height: 0">
- &nbsp;
- </td>
- </tr>
- </table><!
- [endif]-->
- </td>
- </tr>
- <tr>
- <td
- align="center"
- style="
- font-size: 0px;
- padding: 10px 25px;
- padding-top: 0px;
- padding-bottom: 0px;
- word-break: break-word;
- "
- >
- <table
- border="0"
- cellpadding="0"
- cellspacing="0"
- role="presentation"
- style="
- border-collapse: collapse;
- border-spacing: 0px;
- "
- >
- <tbody>
- <tr>
- <td style="width: 121px">
- <img
- alt=""
- height="auto"
- src="https://data.vespa.oath.cloud/assets/vespa-cloud-logo.png"
- style="
- border: none;
- display: block;
- outline: none;
- text-decoration: none;
- height: auto;
- width: 100%;
- font-size: 13px;
- "
- width="121"
- />
- </td>
- </tr>
- </tbody>
- </table>
- </td>
- </tr>
- </tbody>
- </table>
- </div>
- <!--[if mso | IE]></td></tr></table><![endif]-->
- </td>
- </tr>
- </tbody>
- </table>
- </div>
- <!--[if mso | IE]></td></tr></table><table align="center" border="0" cellpadding="0" cellspacing="0" class="" role="presentation" style="width:600px;" width="600" bgcolor="#ffffff" ><tr><td style="line-height:0px;font-size:0px;mso-line-height-rule:exactly;"><![endif]-->
- <div
- style="
- background: #ffffff;
- background-color: #ffffff;
- margin: 0px auto;
- max-width: 600px;
- "
- >
- <table
- align="center"
- border="0"
- cellpadding="0"
- cellspacing="0"
- role="presentation"
- style="background: #ffffff; background-color: #ffffff; width: 100%"
- >
- <tbody>
- <tr>
- <td
- style="
- direction: ltr;
- font-size: 0px;
- padding: 20px 0px 20px 0px;
- padding-bottom: 70px;
- padding-top: 30px;
- text-align: center;
- "
- >
- <!--[if mso | IE]><table role="presentation" border="0" cellpadding="0" cellspacing="0"><tr><td class="" style="vertical-align:top;width:600px;" ><![endif]-->
- <div
- class="mj-column-per-100 mj-outlook-group-fix"
- style="
- font-size: 0px;
- text-align: left;
- direction: ltr;
- display: inline-block;
- vertical-align: top;
- width: 100%;
- "
- >
- <table
- border="0"
- cellpadding="0"
- cellspacing="0"
- role="presentation"
- style="vertical-align: top"
- width="100%"
- >
-
-<tbody>
-<tr>
- <td
- align="left"
- style="
- font-size: 0px;
- padding: 0px 25px 0px 25px;
- padding-top: 0px;
- padding-right: 50px;
- padding-bottom: 0px;
- padding-left: 50px;
- word-break: break-word;
- "
- >
- <div
- style="
- font-family: Open Sans, Helvetica, Arial,
- sans-serif;
- font-size: 13px;
- line-height: 22px;
- text-align: left;
- color: #797e82;
- "
- >
- <h1
- style="
- text-align: center;
- color: #000000;
- line-height: 32px;
- "
- >
- Your Vespa Cloud trial expires in 2 days
- </h1>
- </div>
- </td>
-</tr>
-<tr>
- <td
- align="left"
- style="
- font-size: 0px;
- padding: 0px 25px 0px 25px;
- padding-top: 0px;
- padding-right: 50px;
- padding-bottom: 0px;
- padding-left: 50px;
- word-break: break-word;
- "
- >
- <div
- style="
- font-family: Open Sans, Helvetica, Arial,
- sans-serif;
- font-size: 13px;
- line-height: 22px;
- text-align: left;
- color: #797e82;
- "
- >
-
-<p>
- Your Vespa Cloud trial expires in 2 days. Please reach out to us if you have any questions or feedback.
-</p>
- </div>
- </td>
-</tr>
-<tr>
- <td
- align="center"
- vertical-align="middle"
- style="
- font-size: 0px;
- padding: 10px 25px;
- padding-top: 20px;
- padding-bottom: 20px;
- word-break: break-word;
- "
- >
- <table
- border="0"
- cellpadding="0"
- cellspacing="0"
- role="presentation"
- style="border-collapse: separate; line-height: 100%"
- >
- <tbody>
- <tr>
- <td
- align="center"
- bgcolor="#005A8E"
- role="presentation"
- style="
- border: none;
- border-radius: 100px;
- cursor: auto;
- mso-padding-alt: 15px 25px 15px 25px;
- background: #005a8e;
- "
- valign="middle"
- >
- <a
- href="https://console.tld/tenant/trial-tenant"
- style="
- display: inline-block;
- background: #005a8e;
- color: #ffffff;
- font-family: Open Sans, Helvetica, Arial,
- sans-serif;
- font-size: 13px;
- font-weight: normal;
- line-height: 120%;
- margin: 0;
- text-decoration: none;
- text-transform: none;
- padding: 15px 25px 15px 25px;
- mso-padding-alt: 0px;
- border-radius: 100px;
- "
- target="_blank"
- ><b style="font-weight: 700"
- ><b style="font-weight: 700"
- >Go to Console</b
- ></b
- ></a
- >
- </td>
- </tr>
- </tbody>
- </table>
- </td>
-</tr>
-</tbody>
- </table>
- </div>
- <!--[if mso | IE]></td></tr></table><![endif]-->
- </td>
- </tr>
- </tbody>
- </table>
- </div>
- <!--[if mso | IE]></td></tr></table><table align="center" border="0" cellpadding="0" cellspacing="0" class="" role="presentation" style="width:600px;" width="600" ><tr><td style="line-height:0px;font-size:0px;mso-line-height-rule:exactly;"><![endif]-->
- <div style="margin: 0px auto; max-width: 600px">
- <table
- align="center"
- border="0"
- cellpadding="0"
- cellspacing="0"
- role="presentation"
- style="width: 100%"
- >
- <tbody>
- <tr>
- <td
- style="
- direction: ltr;
- font-size: 0px;
- padding: 20px 0px 20px 0px;
- padding-bottom: 0px;
- padding-top: 20px;
- text-align: center;
- "
- >
- <!--[if mso | IE]><table role="presentation" border="0" cellpadding="0" cellspacing="0"><tr><td class="" style="vertical-align:top;width:600px;" ><![endif]-->
- <div
- class="mj-column-per-100 mj-outlook-group-fix"
- style="
- font-size: 0px;
- text-align: left;
- direction: ltr;
- display: inline-block;
- vertical-align: top;
- width: 100%;
- "
- >
- <table
- border="0"
- cellpadding="0"
- cellspacing="0"
- role="presentation"
- style="vertical-align: top"
- width="100%"
- >
- <tbody>
- <tr>
- <td
- align="center"
- style="
- font-size: 0px;
- padding: 0px 20px 0px 20px;
- padding-top: 0px;
- padding-bottom: 0px;
- word-break: break-word;
- "
- >
- <div
- style="
- font-family: Open Sans, Helvetica, Arial,
- sans-serif;
- font-size: 11px;
- line-height: 22px;
- text-align: center;
- color: #797e82;
- "
- >
- <p style="margin: 10px 0">
- <a
- target="_blank"
- rel="noopener noreferrer"
- style="color: #005a8e"
- href="https://legal.yahoo.com/xw/en/yahoo/privacy/topic/b2bprivacypolicy/index.html"
- ><span style="color: #005a8e"
- >Yahoo Privacy Policy</span
- ></a
- ><span style="color: #797e82"
- >&nbsp; &nbsp;|&nbsp; &nbsp;</span
- ><a
- target="_blank"
- rel="noopener noreferrer"
- style="color: #005a8e"
- href="https://console.tld/terms-of-service-trial.html"
- ><span style="color: #005a8e"
- >Terms of Service</span
- ></a
- ><span style="color: #797e82"
- >&nbsp; &nbsp;|&nbsp; &nbsp;</span
- ><a
- target="_blank"
- rel="noopener noreferrer"
- style="color: #005a8e"
- href="https://console.tld/support"
- ><span style="color: #005a8e">Support</span></a
- >
- </p>
- <p style="margin: 10px 0">
- <a
- target="_blank"
- rel="noopener noreferrer"
- style="color: inherit; text-decoration: none"
- href="https://console.tld/tenant/trial-tenant/account/notifications"
- >Click
- <span style="color: #005a8e"><u>here</u></span>
- to manage your notifications setting.</a
- ><br />
- </p>
- </div>
- </td>
- </tr>
- </tbody>
- </table>
- </div>
- <!--[if mso | IE]></td></tr></table><![endif]-->
- </td>
- </tr>
- </tbody>
- </table>
- </div>
- <!--[if mso | IE]></td></tr></table><![endif]-->
- </div>
- </body>
-</html>
diff --git a/controller-server/src/test/resources/mail/trial-reminder.html b/controller-server/src/test/resources/mail/trial-midway-checkin.html
index fbe0d573538..fbe0d573538 100644
--- a/controller-server/src/test/resources/mail/trial-reminder.html
+++ b/controller-server/src/test/resources/mail/trial-midway-checkin.html
diff --git a/controller-server/src/test/resources/mail/welcome.html b/controller-server/src/test/resources/mail/trial-signed-up.html
index 2e652532db8..2e652532db8 100644
--- a/controller-server/src/test/resources/mail/welcome.html
+++ b/controller-server/src/test/resources/mail/trial-signed-up.html