Details
diff --git a/api/src/main/java/com/ning/billing/overdue/EmailNotification.java b/api/src/main/java/com/ning/billing/overdue/EmailNotification.java
new file mode 100644
index 0000000..a8e4bf5
--- /dev/null
+++ b/api/src/main/java/com/ning/billing/overdue/EmailNotification.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.overdue;
+
+public interface EmailNotification {
+
+ public String getSubject();
+
+ public String getTemplateName();
+
+ public Boolean isHTML();
+}
diff --git a/api/src/main/java/com/ning/billing/overdue/OverdueState.java b/api/src/main/java/com/ning/billing/overdue/OverdueState.java
index 0c216b1..897f6db 100644
--- a/api/src/main/java/com/ning/billing/overdue/OverdueState.java
+++ b/api/src/main/java/com/ning/billing/overdue/OverdueState.java
@@ -20,7 +20,6 @@ import org.joda.time.Period;
import com.ning.billing.junction.api.Blockable;
-
public interface OverdueState<T extends Blockable> {
public String getName();
@@ -40,4 +39,6 @@ public interface OverdueState<T extends Blockable> {
public Period getReevaluationInterval() throws OverdueApiException;
public Condition<T> getCondition();
+
+ public EmailNotification getEnterStateEmailNotification();
}
diff --git a/api/src/main/java/com/ning/billing/util/email/EmailSender.java b/api/src/main/java/com/ning/billing/util/email/EmailSender.java
index 198a2eb..f877937 100644
--- a/api/src/main/java/com/ning/billing/util/email/EmailSender.java
+++ b/api/src/main/java/com/ning/billing/util/email/EmailSender.java
@@ -20,5 +20,8 @@ import java.io.IOException;
import java.util.List;
public interface EmailSender {
- public void sendSecureEmail(List<String> to, List<String> cc, String subject, String htmlBody) throws IOException, EmailApiException;
+
+ public void sendHTMLEmail(List<String> to, List<String> cc, String subject, String htmlBody) throws IOException, EmailApiException;
+
+ public void sendPlainTextEmail(List<String> to, List<String> cc, String subject, String body) throws IOException, EmailApiException;
}
diff --git a/invoice/src/main/java/com/ning/billing/invoice/notification/EmailInvoiceNotifier.java b/invoice/src/main/java/com/ning/billing/invoice/notification/EmailInvoiceNotifier.java
index 10d7202..aa63fe3 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/notification/EmailInvoiceNotifier.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/notification/EmailInvoiceNotifier.java
@@ -86,7 +86,7 @@ public class EmailInvoiceNotifier implements InvoiceNotifier {
final EmailSender sender = new DefaultEmailSender(config);
try {
- sender.sendSecureEmail(to, cc, subject, htmlBody);
+ sender.sendHTMLEmail(to, cc, subject, htmlBody);
} catch (EmailApiException e) {
throw new InvoiceApiException(e, ErrorCode.EMAIL_SENDING_FAILED);
} catch (IOException e) {
diff --git a/overdue/src/main/java/com/ning/billing/overdue/applicator/OverdueEmailGenerator.java b/overdue/src/main/java/com/ning/billing/overdue/applicator/OverdueEmailGenerator.java
new file mode 100644
index 0000000..ec2f971
--- /dev/null
+++ b/overdue/src/main/java/com/ning/billing/overdue/applicator/OverdueEmailGenerator.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.overdue.applicator;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+import com.ning.billing.account.api.Account;
+import com.ning.billing.junction.api.Blockable;
+import com.ning.billing.overdue.OverdueState;
+import com.ning.billing.overdue.config.api.BillingState;
+import com.ning.billing.util.email.templates.TemplateEngine;
+
+import com.google.inject.Inject;
+
+public class OverdueEmailGenerator {
+
+ private final TemplateEngine templateEngine;
+
+ @Inject
+ public OverdueEmailGenerator(final TemplateEngine templateEngine) {
+ this.templateEngine = templateEngine;
+ }
+
+ public <T extends Blockable> String generateEmail(final Account account, final BillingState<T> billingState,
+ final T overdueable, final OverdueState<T> nextOverdueState) throws IOException {
+ final Map<String, Object> data = new HashMap<String, Object>();
+
+ // TODO raw objects for now. We eventually should respect the account locale and support translations
+ data.put("account", account);
+ data.put("billingState", billingState);
+ data.put("overdueable", overdueable);
+ data.put("nextOverdueState", nextOverdueState);
+
+ // TODO single template for all languages for now
+ return templateEngine.executeTemplate(nextOverdueState.getEnterStateEmailNotification().getTemplateName(), data);
+ }
+}
diff --git a/overdue/src/main/java/com/ning/billing/overdue/applicator/OverdueStateApplicator.java b/overdue/src/main/java/com/ning/billing/overdue/applicator/OverdueStateApplicator.java
index a5d44da..7492ae9 100644
--- a/overdue/src/main/java/com/ning/billing/overdue/applicator/OverdueStateApplicator.java
+++ b/overdue/src/main/java/com/ning/billing/overdue/applicator/OverdueStateApplicator.java
@@ -16,8 +16,10 @@
package com.ning.billing.overdue.applicator;
+import java.io.IOException;
import java.util.LinkedList;
import java.util.List;
+import java.util.UUID;
import org.joda.time.DateTime;
import org.joda.time.LocalDate;
@@ -27,12 +29,15 @@ import org.slf4j.LoggerFactory;
import com.ning.billing.ErrorCode;
import com.ning.billing.account.api.Account;
+import com.ning.billing.account.api.AccountApiException;
+import com.ning.billing.account.api.AccountUserApi;
import com.ning.billing.catalog.api.ActionPolicy;
import com.ning.billing.entitlement.api.user.EntitlementUserApi;
import com.ning.billing.entitlement.api.user.EntitlementUserApiException;
import com.ning.billing.entitlement.api.user.Subscription;
import com.ning.billing.entitlement.api.user.SubscriptionBundle;
import com.ning.billing.junction.api.Blockable;
+import com.ning.billing.junction.api.Blockable.Type;
import com.ning.billing.junction.api.BlockingApi;
import com.ning.billing.junction.api.BlockingApiException;
import com.ning.billing.junction.api.DefaultBlockingState;
@@ -50,8 +55,14 @@ import com.ning.billing.util.callcontext.CallContextFactory;
import com.ning.billing.util.callcontext.CallOrigin;
import com.ning.billing.util.callcontext.UserType;
import com.ning.billing.util.clock.Clock;
+import com.ning.billing.util.email.DefaultEmailSender;
+import com.ning.billing.util.email.EmailApiException;
+import com.ning.billing.util.email.EmailConfig;
+import com.ning.billing.util.email.EmailSender;
+import com.google.common.collect.ImmutableList;
import com.google.inject.Inject;
+import com.samskivert.mustache.MustacheException;
public class OverdueStateApplicator<T extends Blockable> {
@@ -63,16 +74,23 @@ public class OverdueStateApplicator<T extends Blockable> {
private final Clock clock;
private final OverdueCheckPoster poster;
private final Bus bus;
+ private final AccountUserApi accountUserApi;
private final EntitlementUserApi entitlementUserApi;
private final CallContextFactory factory;
+ private final OverdueEmailGenerator overdueEmailGenerator;
+ private final EmailSender emailSender;
@Inject
- public OverdueStateApplicator(final BlockingApi accessApi, final EntitlementUserApi entitlementUserApi, final Clock clock,
- final OverdueCheckPoster poster, final Bus bus, final CallContextFactory factory) {
+ public OverdueStateApplicator(final BlockingApi accessApi, final AccountUserApi accountUserApi, final EntitlementUserApi entitlementUserApi,
+ final Clock clock, final OverdueCheckPoster poster, final OverdueEmailGenerator overdueEmailGenerator,
+ final EmailConfig config, final Bus bus, final CallContextFactory factory) {
this.blockingApi = accessApi;
+ this.accountUserApi = accountUserApi;
this.entitlementUserApi = entitlementUserApi;
this.clock = clock;
this.poster = poster;
+ this.overdueEmailGenerator = overdueEmailGenerator;
+ this.emailSender = new DefaultEmailSender(config);
this.bus = bus;
this.factory = factory;
}
@@ -91,13 +109,16 @@ public class OverdueStateApplicator<T extends Blockable> {
}
if (previousOverdueStateName.equals(nextOverdueState.getName())) {
- return; //That's it we are done...
+ return; // That's it, we are done...
}
storeNewState(overdueable, nextOverdueState);
cancelSubscriptionsIfRequired(overdueable, nextOverdueState);
+ sendEmailIfRequired(billingState, overdueable, nextOverdueState);
+
+ // Add entry in notification queue
final Period reevaluationInterval = nextOverdueState.getReevaluationInterval();
if (!nextOverdueState.isClearState()) {
createFutureNotification(overdueable, clock.getUTCNow().plus(reevaluationInterval));
@@ -158,7 +179,7 @@ public class OverdueStateApplicator<T extends Blockable> {
return;
}
try {
- ActionPolicy actionPolicy = null;
+ final ActionPolicy actionPolicy;
switch (nextOverdueState.getSubscriptionCancellationPolicy()) {
case END_OF_TERM:
actionPolicy = ActionPolicy.END_OF_TERM;
@@ -194,4 +215,62 @@ public class OverdueStateApplicator<T extends Blockable> {
}
}
}
+
+ private void sendEmailIfRequired(final BillingState<T> billingState, final T overdueable, final OverdueState<T> nextOverdueState) {
+ // Note: we don't want to fail the full refresh call because sending the email failed.
+ // That's the reason why we catch all exceptions here.
+ // The alternative would be to: throw new OverdueApiException(e, ErrorCode.EMAIL_SENDING_FAILED);
+
+ // If sending is not configured, skip
+ if (nextOverdueState.getEnterStateEmailNotification() == null) {
+ return;
+ }
+
+ // Retrieve the account
+ final Account account;
+ final Type overdueableType = Blockable.Type.get(overdueable);
+ try {
+ if (Type.SUBSCRIPTION.equals(overdueableType)) {
+ final UUID bundleId = ((Subscription) overdueable).getBundleId();
+ final SubscriptionBundle bundle = entitlementUserApi.getBundleFromId(bundleId);
+ account = accountUserApi.getAccountById(bundle.getAccountId());
+ } else if (Type.SUBSCRIPTION_BUNDLE.equals(overdueableType)) {
+ final UUID bundleId = ((SubscriptionBundle) overdueable).getId();
+ final SubscriptionBundle bundle = entitlementUserApi.getBundleFromId(bundleId);
+ account = accountUserApi.getAccountById(bundle.getAccountId());
+ } else if (Type.ACCOUNT.equals(overdueableType)) {
+ account = (Account) overdueable;
+ } else {
+ log.warn("Unable to retrieve account for overdueable {} (type {})", overdueable.getId(), overdueableType);
+ return;
+ }
+ } catch (EntitlementUserApiException e) {
+ log.warn(String.format("Unable to retrieve account for overdueable %s (type %s)", overdueable.getId(), overdueableType), e);
+ return;
+ } catch (AccountApiException e) {
+ log.warn(String.format("Unable to retrieve account for overdueable %s (type %s)", overdueable.getId(), overdueableType), e);
+ return;
+ }
+
+ final List<String> to = ImmutableList.<String>of(account.getEmail());
+ // TODO - should we look at the account CC: list?
+ final List<String> cc = ImmutableList.<String>of();
+ final String subject = nextOverdueState.getEnterStateEmailNotification().getSubject();
+
+ try {
+ // Generate and send the email
+ final String emailBody = overdueEmailGenerator.generateEmail(account, billingState, overdueable, nextOverdueState);
+ if (nextOverdueState.getEnterStateEmailNotification().isHTML()) {
+ emailSender.sendHTMLEmail(to, cc, subject, emailBody);
+ } else {
+ emailSender.sendPlainTextEmail(to, cc, subject, emailBody);
+ }
+ } catch (IOException e) {
+ log.warn(String.format("Unable to generate or send overdue notification email for account %s and overdueable %s", account.getId(), overdueable.getId()), e);
+ } catch (EmailApiException e) {
+ log.warn(String.format("Unable to send overdue notification email for account %s and overdueable %s", account.getId(), overdueable.getId()), e);
+ } catch (MustacheException e) {
+ log.warn(String.format("Unable to generate overdue notification email for account %s and overdueable %s", account.getId(), overdueable.getId()), e);
+ }
+ }
}
diff --git a/overdue/src/main/java/com/ning/billing/overdue/config/DefaultEmailNotification.java b/overdue/src/main/java/com/ning/billing/overdue/config/DefaultEmailNotification.java
new file mode 100644
index 0000000..a5491d3
--- /dev/null
+++ b/overdue/src/main/java/com/ning/billing/overdue/config/DefaultEmailNotification.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.overdue.config;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+
+import com.ning.billing.overdue.EmailNotification;
+
+@XmlAccessorType(XmlAccessType.NONE)
+public class DefaultEmailNotification implements EmailNotification {
+
+ @XmlElement(required = true, name = "subject")
+ private String subject;
+
+ @XmlElement(required = true, name = "templateName")
+ private String templateName;
+
+ @XmlElement(required = false, name = "isHTML")
+ private Boolean isHTML = false;
+
+ @Override
+ public String getSubject() {
+ return subject;
+ }
+
+ @Override
+ public String getTemplateName() {
+ return templateName;
+ }
+
+ @Override
+ public Boolean isHTML() {
+ return isHTML;
+ }
+}
diff --git a/overdue/src/main/java/com/ning/billing/overdue/config/DefaultOverdueState.java b/overdue/src/main/java/com/ning/billing/overdue/config/DefaultOverdueState.java
index 7cbc01f..d95b487 100644
--- a/overdue/src/main/java/com/ning/billing/overdue/config/DefaultOverdueState.java
+++ b/overdue/src/main/java/com/ning/billing/overdue/config/DefaultOverdueState.java
@@ -27,6 +27,7 @@ import org.joda.time.Period;
import com.ning.billing.ErrorCode;
import com.ning.billing.catalog.api.TimeUnit;
import com.ning.billing.junction.api.Blockable;
+import com.ning.billing.overdue.EmailNotification;
import com.ning.billing.overdue.OverdueApiException;
import com.ning.billing.overdue.OverdueCancellationPolicicy;
import com.ning.billing.overdue.OverdueState;
@@ -64,8 +65,10 @@ public class DefaultOverdueState<T extends Blockable> extends ValidatingConfig<O
@XmlElement(required = false, name = "autoReevaluationInterval")
private DefaultDuration autoReevaluationInterval;
+ @XmlElement(required = false, name = "enterStateEmailNotification")
+ private DefaultEmailNotification enterStateEmailNotification;
+
//Other actions could include
- // - send email
// - trigger payment retry?
// - add tagStore to bundle/account
// - set payment failure email template
@@ -163,4 +166,9 @@ public class DefaultOverdueState<T extends Blockable> extends ValidatingConfig<O
public int getDaysBetweenPaymentRetries() {
return 8;
}
+
+ @Override
+ public EmailNotification getEnterStateEmailNotification() {
+ return enterStateEmailNotification;
+ }
}
diff --git a/overdue/src/main/java/com/ning/billing/overdue/glue/DefaultOverdueModule.java b/overdue/src/main/java/com/ning/billing/overdue/glue/DefaultOverdueModule.java
index 2072e5e..baf8700 100644
--- a/overdue/src/main/java/com/ning/billing/overdue/glue/DefaultOverdueModule.java
+++ b/overdue/src/main/java/com/ning/billing/overdue/glue/DefaultOverdueModule.java
@@ -27,6 +27,7 @@ import com.ning.billing.overdue.OverdueProperties;
import com.ning.billing.overdue.OverdueService;
import com.ning.billing.overdue.OverdueUserApi;
import com.ning.billing.overdue.api.DefaultOverdueUserApi;
+import com.ning.billing.overdue.applicator.OverdueEmailGenerator;
import com.ning.billing.overdue.service.DefaultOverdueService;
import com.ning.billing.overdue.service.ExtendedOverdueService;
import com.ning.billing.overdue.wrapper.OverdueWrapperFactory;
@@ -42,6 +43,7 @@ public class DefaultOverdueModule extends AbstractModule implements OverdueModul
// internal bindings
installOverdueService();
installOverdueWrapperFactory();
+ installOverdueEmail();
final OverdueProperties config = new ConfigurationObjectFactory(System.getProperties()).build(OverdueProperties.class);
bind(OverdueProperties.class).toInstance(config);
@@ -58,6 +60,10 @@ public class DefaultOverdueModule extends AbstractModule implements OverdueModul
bind(OverdueWrapperFactory.class).asEagerSingleton();
}
+ protected void installOverdueEmail() {
+ bind(OverdueEmailGenerator.class).asEagerSingleton();
+ }
+
@Override
public void installOverdueUserApi() {
bind(OverdueUserApi.class).to(DefaultOverdueUserApi.class).asEagerSingleton();
diff --git a/overdue/src/test/java/com/ning/billing/overdue/config/TestOverdueConfig.java b/overdue/src/test/java/com/ning/billing/overdue/config/TestOverdueConfig.java
index 2b2c264..534f12f 100644
--- a/overdue/src/test/java/com/ning/billing/overdue/config/TestOverdueConfig.java
+++ b/overdue/src/test/java/com/ning/billing/overdue/config/TestOverdueConfig.java
@@ -19,45 +19,59 @@ package com.ning.billing.overdue.config;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
+import org.testng.Assert;
import org.testng.annotations.Test;
+import com.ning.billing.overdue.EmailNotification;
import com.ning.billing.overdue.OverdueTestSuite;
import com.ning.billing.util.config.XMLLoader;
public class TestOverdueConfig extends OverdueTestSuite {
+
@Test(groups = "fast")
public void testParseConfig() throws Exception {
final String xml = "<overdueConfig>" +
- " <bundleOverdueStates>" +
- " <state name=\"OD1\">" +
- " <condition>" +
- " <timeSinceEarliestUnpaidInvoiceEqualsOrExceeds>" +
- " <unit>MONTHS</unit><number>1</number>" +
- " </timeSinceEarliestUnpaidInvoiceEqualsOrExceeds>" +
- " </condition>" +
- " <externalMessage>Reached OD1</externalMessage>" +
- " <blockChanges>true</blockChanges>" +
- " <disableEntitlementAndChangesBlocked>false</disableEntitlementAndChangesBlocked>" +
- " <autoReevaluationInterval>" +
- " <unit>DAYS</unit><number>15</number>" +
- " </autoReevaluationInterval>" +
- " </state>" +
- " <state name=\"OD2\">" +
- " <condition>" +
- " <timeSinceEarliestUnpaidInvoiceEqualsOrExceeds>" +
- " <unit>MONTHS</unit><number>2</number>" +
- " </timeSinceEarliestUnpaidInvoiceEqualsOrExceeds>" +
- " </condition>" +
- " <externalMessage>Reached OD1</externalMessage>" +
- " <blockChanges>true</blockChanges>" +
- " <disableEntitlementAndChangesBlocked>true</disableEntitlementAndChangesBlocked>" +
- " <autoReevaluationInterval>" +
- " <unit>DAYS</unit><number>15</number>" +
- " </autoReevaluationInterval>" +
- " </state>" +
- " </bundleOverdueStates>" +
- "</overdueConfig>";
+ " <bundleOverdueStates>" +
+ " <state name=\"OD1\">" +
+ " <condition>" +
+ " <timeSinceEarliestUnpaidInvoiceEqualsOrExceeds>" +
+ " <unit>MONTHS</unit><number>1</number>" +
+ " </timeSinceEarliestUnpaidInvoiceEqualsOrExceeds>" +
+ " </condition>" +
+ " <externalMessage>Reached OD1</externalMessage>" +
+ " <blockChanges>true</blockChanges>" +
+ " <disableEntitlementAndChangesBlocked>false</disableEntitlementAndChangesBlocked>" +
+ " <autoReevaluationInterval>" +
+ " <unit>DAYS</unit><number>15</number>" +
+ " </autoReevaluationInterval>" +
+ " </state>" +
+ " <state name=\"OD2\">" +
+ " <condition>" +
+ " <timeSinceEarliestUnpaidInvoiceEqualsOrExceeds>" +
+ " <unit>MONTHS</unit><number>2</number>" +
+ " </timeSinceEarliestUnpaidInvoiceEqualsOrExceeds>" +
+ " </condition>" +
+ " <externalMessage>Reached OD1</externalMessage>" +
+ " <blockChanges>true</blockChanges>" +
+ " <disableEntitlementAndChangesBlocked>true</disableEntitlementAndChangesBlocked>" +
+ " <autoReevaluationInterval>" +
+ " <unit>DAYS</unit><number>15</number>" +
+ " </autoReevaluationInterval>" +
+ " <enterStateEmailNotification>" +
+ " <subject>ToTo</subject><templateName>Titi</templateName>" +
+ " </enterStateEmailNotification>" +
+ " </state>" +
+ " </bundleOverdueStates>" +
+ "</overdueConfig>";
final InputStream is = new ByteArrayInputStream(xml.getBytes());
final OverdueConfig c = XMLLoader.getObjectFromStreamNoValidation(is, OverdueConfig.class);
+ Assert.assertEquals(c.getBundleStateSet().size(), 2);
+
+ Assert.assertNull(c.getBundleStateSet().getStates()[0].getEnterStateEmailNotification());
+
+ final EmailNotification secondNotification = c.getBundleStateSet().getStates()[1].getEnterStateEmailNotification();
+ Assert.assertEquals(secondNotification.getSubject(), "ToTo");
+ Assert.assertEquals(secondNotification.getTemplateName(), "Titi");
+ Assert.assertFalse(secondNotification.isHTML());
}
}
diff --git a/overdue/src/test/java/com/ning/billing/overdue/notification/TestOverdueCheckNotifier.java b/overdue/src/test/java/com/ning/billing/overdue/notification/TestOverdueCheckNotifier.java
index d2cecf1..2cd0dc0 100644
--- a/overdue/src/test/java/com/ning/billing/overdue/notification/TestOverdueCheckNotifier.java
+++ b/overdue/src/test/java/com/ning/billing/overdue/notification/TestOverdueCheckNotifier.java
@@ -63,6 +63,8 @@ import com.ning.billing.util.clock.Clock;
import com.ning.billing.util.clock.ClockMock;
import com.ning.billing.util.customfield.dao.AuditedCustomFieldDao;
import com.ning.billing.util.customfield.dao.CustomFieldDao;
+import com.ning.billing.util.email.EmailModule;
+import com.ning.billing.util.email.templates.TemplateModule;
import com.ning.billing.util.globallocker.GlobalLocker;
import com.ning.billing.util.globallocker.MySqlGlobalLocker;
import com.ning.billing.util.glue.BusModule;
@@ -130,6 +132,8 @@ public class TestOverdueCheckNotifier extends OverdueTestSuiteWithEmbeddedDB {
bind(GlobalLocker.class).to(MySqlGlobalLocker.class).asEagerSingleton();
bind(ChargeThruApi.class).toInstance(Mockito.mock(ChargeThruApi.class));
install(new MockJunctionModule());
+ install(new EmailModule());
+ install(new TemplateModule());
}
});
diff --git a/overdue/src/test/java/com/ning/billing/overdue/OverdueTestBase.java b/overdue/src/test/java/com/ning/billing/overdue/OverdueTestBase.java
index 6b8d67e..477d1bb 100644
--- a/overdue/src/test/java/com/ning/billing/overdue/OverdueTestBase.java
+++ b/overdue/src/test/java/com/ning/billing/overdue/OverdueTestBase.java
@@ -60,11 +60,15 @@ import com.ning.billing.overdue.service.DefaultOverdueService;
import com.ning.billing.overdue.wrapper.OverdueWrapperFactory;
import com.ning.billing.util.bus.BusService;
import com.ning.billing.util.clock.ClockMock;
+import com.ning.billing.util.email.EmailModule;
+import com.ning.billing.util.email.templates.TemplateModule;
import com.ning.billing.util.glue.CallContextModule;
import com.ning.billing.util.glue.NotificationQueueModule;
import com.ning.billing.util.notificationq.NotificationQueueService.NotificationQueueAlreadyExists;
-@Guice(modules = {DefaultOverdueModule.class, OverdueListenerTesterModule.class, MockClockModule.class, ApplicatorMockJunctionModule.class, CallContextModule.class, CatalogModule.class, MockInvoiceModule.class, MockPaymentModule.class, NotificationQueueModule.class, TestDbiModule.class})
+@Guice(modules = {DefaultOverdueModule.class, OverdueListenerTesterModule.class, MockClockModule.class, ApplicatorMockJunctionModule.class,
+ CallContextModule.class, CatalogModule.class, MockInvoiceModule.class, MockPaymentModule.class, NotificationQueueModule.class,
+ EmailModule.class, TemplateModule.class, TestDbiModule.class})
public abstract class OverdueTestBase extends OverdueTestSuiteWithEmbeddedDB {
protected final String configXml =
"<overdueConfig>" +
diff --git a/util/src/main/java/com/ning/billing/util/email/DefaultEmailSender.java b/util/src/main/java/com/ning/billing/util/email/DefaultEmailSender.java
index 48d6594..a238c8c 100644
--- a/util/src/main/java/com/ning/billing/util/email/DefaultEmailSender.java
+++ b/util/src/main/java/com/ning/billing/util/email/DefaultEmailSender.java
@@ -16,17 +16,22 @@
package com.ning.billing.util.email;
+import java.io.IOException;
import java.util.List;
+import org.apache.commons.mail.Email;
import org.apache.commons.mail.EmailException;
import org.apache.commons.mail.HtmlEmail;
+import org.apache.commons.mail.SimpleEmail;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import com.google.inject.Inject;
import com.ning.billing.ErrorCode;
+import com.google.inject.Inject;
+
public class DefaultEmailSender implements EmailSender {
+
private final Logger log = LoggerFactory.getLogger(EmailSender.class);
private final EmailConfig config;
@@ -36,11 +41,31 @@ public class DefaultEmailSender implements EmailSender {
}
@Override
- public void sendSecureEmail(final List<String> to, final List<String> cc, final String subject, final String htmlBody) throws EmailApiException {
- final HtmlEmail email;
+ public void sendHTMLEmail(final List<String> to, final List<String> cc, final String subject, final String htmlBody) throws EmailApiException {
+ final HtmlEmail email = new HtmlEmail();
+ try {
+ email.setHtmlMsg(htmlBody);
+ } catch (EmailException e) {
+ throw new EmailApiException(e, ErrorCode.EMAIL_SENDING_FAILED);
+ }
+
+ sendEmail(to, cc, subject, email);
+ }
+
+ @Override
+ public void sendPlainTextEmail(final List<String> to, final List<String> cc, final String subject, final String body) throws IOException, EmailApiException {
+ final SimpleEmail email = new SimpleEmail();
try {
- email = new HtmlEmail();
+ email.setMsg(body);
+ } catch (EmailException e) {
+ throw new EmailApiException(e, ErrorCode.EMAIL_SENDING_FAILED);
+ }
+ sendEmail(to, cc, subject, email);
+ }
+
+ private void sendEmail(final List<String> to, final List<String> cc, final String subject, final Email email) throws EmailApiException {
+ try {
email.setSmtpPort(config.getSmtpPort());
if (config.useSmtpAuth()) {
email.setAuthentication(config.getSmtpUserName(), config.getSmtpPassword());
@@ -49,7 +74,6 @@ public class DefaultEmailSender implements EmailSender {
email.setFrom(config.getDefaultFrom());
email.setSubject(subject);
- email.setHtmlMsg(htmlBody);
if (to != null) {
for (final String recipient : to) {
diff --git a/util/src/test/java/com/ning/billing/util/email/EmailSenderTest.java b/util/src/test/java/com/ning/billing/util/email/EmailSenderTest.java
index 81b40d9..0fb604f 100644
--- a/util/src/test/java/com/ning/billing/util/email/EmailSenderTest.java
+++ b/util/src/test/java/com/ning/billing/util/email/EmailSenderTest.java
@@ -39,6 +39,6 @@ public class EmailSenderTest extends UtilTestSuite {
recipients.add("killbill.ning@gmail.com");
final EmailSender sender = new DefaultEmailSender(config);
- sender.sendSecureEmail(recipients, null, "Test message", html);
+ sender.sendHTMLEmail(recipients, null, "Test message", html);
}
}