Details
diff --git a/api/src/main/java/com/ning/billing/payment/api/PaymentApi.java b/api/src/main/java/com/ning/billing/payment/api/PaymentApi.java
index fd84927..57c76a0 100644
--- a/api/src/main/java/com/ning/billing/payment/api/PaymentApi.java
+++ b/api/src/main/java/com/ning/billing/payment/api/PaymentApi.java
@@ -39,7 +39,7 @@ public interface PaymentApi {
List<Either<PaymentError, PaymentInfo>> createPayment(String accountKey, List<String> invoiceIds);
List<Either<PaymentError, PaymentInfo>> createPayment(Account account, List<String> invoiceIds);
- Either<PaymentError, PaymentInfo> createPayment(UUID paymentAttemptId);
+ Either<PaymentError, PaymentInfo> createPaymentForPaymentAttempt(UUID paymentAttemptId);
List<Either<PaymentError, PaymentInfo>> createRefund(Account account, List<String> invoiceIds); //TODO
diff --git a/payment/src/main/java/com/ning/billing/payment/api/DefaultPaymentApi.java b/payment/src/main/java/com/ning/billing/payment/api/DefaultPaymentApi.java
index d2f5c7c..7f40a5c 100644
--- a/payment/src/main/java/com/ning/billing/payment/api/DefaultPaymentApi.java
+++ b/payment/src/main/java/com/ning/billing/payment/api/DefaultPaymentApi.java
@@ -25,7 +25,6 @@ import javax.annotation.Nullable;
import org.apache.commons.lang.StringUtils;
import org.joda.time.DateTime;
-import org.joda.time.DateTimeZone;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -35,6 +34,7 @@ import com.ning.billing.account.api.AccountUserApi;
import com.ning.billing.invoice.api.Invoice;
import com.ning.billing.invoice.api.InvoicePaymentApi;
import com.ning.billing.invoice.model.DefaultInvoicePayment;
+import com.ning.billing.payment.RetryService;
import com.ning.billing.payment.dao.PaymentDao;
import com.ning.billing.payment.provider.PaymentProviderPlugin;
import com.ning.billing.payment.provider.PaymentProviderPluginRegistry;
@@ -44,6 +44,7 @@ public class DefaultPaymentApi implements PaymentApi {
private final PaymentProviderPluginRegistry pluginRegistry;
private final AccountUserApi accountUserApi;
private final InvoicePaymentApi invoicePaymentApi;
+ private final RetryService retryService;
private final PaymentDao paymentDao;
private final PaymentConfig config;
@@ -53,11 +54,13 @@ public class DefaultPaymentApi implements PaymentApi {
public DefaultPaymentApi(PaymentProviderPluginRegistry pluginRegistry,
AccountUserApi accountUserApi,
InvoicePaymentApi invoicePaymentApi,
+ RetryService retryService,
PaymentDao paymentDao,
PaymentConfig config) {
this.pluginRegistry = pluginRegistry;
this.accountUserApi = accountUserApi;
this.invoicePaymentApi = invoicePaymentApi;
+ this.retryService = retryService;
this.paymentDao = paymentDao;
this.config = config;
}
@@ -134,7 +137,7 @@ public class DefaultPaymentApi implements PaymentApi {
}
@Override
- public Either<PaymentError, PaymentInfo> createPayment(UUID paymentAttemptId) {
+ public Either<PaymentError, PaymentInfo> createPaymentForPaymentAttempt(UUID paymentAttemptId) {
PaymentAttempt paymentAttempt = paymentDao.getPaymentAttemptById(paymentAttemptId);
if (paymentAttempt != null) {
@@ -235,7 +238,7 @@ public class DefaultPaymentApi implements PaymentApi {
if (retryCount < retryDays.size()) {
int retryInDays = 0;
- DateTime nextRetryDate = new DateTime(DateTimeZone.UTC);
+ DateTime nextRetryDate = paymentAttempt.getPaymentAttemptDate();
try {
retryInDays = retryDays.get(retryCount);
@@ -245,6 +248,7 @@ public class DefaultPaymentApi implements PaymentApi {
log.error("Could not get retry day for retry count {}", retryCount);
}
+ retryService.scheduleRetry(paymentAttempt, nextRetryDate);
paymentDao.updatePaymentAttemptWithRetryInfo(paymentAttempt.getPaymentAttemptId(), retryCount + 1, nextRetryDate);
}
else if (retryCount == retryDays.size()) {
diff --git a/payment/src/main/java/com/ning/billing/payment/dao/DefaultPaymentDao.java b/payment/src/main/java/com/ning/billing/payment/dao/DefaultPaymentDao.java
index a86db13..aee9854 100644
--- a/payment/src/main/java/com/ning/billing/payment/dao/DefaultPaymentDao.java
+++ b/payment/src/main/java/com/ning/billing/payment/dao/DefaultPaymentDao.java
@@ -86,7 +86,7 @@ public class DefaultPaymentDao implements PaymentDao {
@Override
public void updatePaymentAttemptWithRetryInfo(UUID paymentAttemptId, int retryCount, DateTime nextRetryDate) {
- sqlDao.updatePaymentAttemptWithRetryInfo(paymentAttemptId.toString(), retryCount, nextRetryDate);
+ sqlDao.updatePaymentAttemptWithRetryInfo(paymentAttemptId.toString(), retryCount, nextRetryDate == null ? null : nextRetryDate.toDate());
}
@Override
diff --git a/payment/src/main/java/com/ning/billing/payment/dao/PaymentSqlDao.java b/payment/src/main/java/com/ning/billing/payment/dao/PaymentSqlDao.java
index 9919d34..a7feae3 100644
--- a/payment/src/main/java/com/ning/billing/payment/dao/PaymentSqlDao.java
+++ b/payment/src/main/java/com/ning/billing/payment/dao/PaymentSqlDao.java
@@ -76,7 +76,7 @@ public interface PaymentSqlDao extends Transactional<PaymentSqlDao>, CloseMe, Tr
@SqlUpdate
void updatePaymentAttemptWithRetryInfo(@Bind("payment_attempt_id") String paymentAttemptId,
@Bind("retry_count") int retryCount,
- @Bind("next_retry_dt") DateTime nextRetryDate);
+ @Bind("next_retry_dt") Date nextRetryDate);
@SqlUpdate
void updatePaymentInfo(@Bind("payment_method") String paymentMethod,
diff --git a/payment/src/main/java/com/ning/billing/payment/RetryService.java b/payment/src/main/java/com/ning/billing/payment/RetryService.java
index bbe8a61..ee57397 100644
--- a/payment/src/main/java/com/ning/billing/payment/RetryService.java
+++ b/payment/src/main/java/com/ning/billing/payment/RetryService.java
@@ -19,7 +19,6 @@ package com.ning.billing.payment;
import java.util.UUID;
import org.joda.time.DateTime;
-import org.skife.jdbi.v2.sqlobject.mixins.Transmogrifier;
import com.google.inject.Inject;
import com.ning.billing.lifecycle.KillbillService;
@@ -82,7 +81,7 @@ public class RetryService implements KillbillService {
}
}
- public void scheduleRetry(Transmogrifier transactionalDao, PaymentAttempt paymentAttempt, DateTime timeOfRetry) {
+ public void scheduleRetry(PaymentAttempt paymentAttempt, DateTime timeOfRetry) {
final String id = paymentAttempt.getPaymentAttemptId().toString();
NotificationKey key = new NotificationKey() {
@@ -91,14 +90,14 @@ public class RetryService implements KillbillService {
return id;
}
};
- retryQueue.recordFutureNotificationFromTransaction(transactionalDao, timeOfRetry, key);
+ retryQueue.recordFutureNotification(timeOfRetry, key);
}
private void retry(String paymentAttemptId) {
PaymentInfo paymentInfo = paymentApi.getPaymentInfoForPaymentAttemptId(paymentAttemptId);
- if (paymentInfo != null && !PaymentStatus.Processed.equals(PaymentStatus.valueOf(paymentInfo.getStatus()))) {
- paymentApi.createPayment(UUID.fromString(paymentAttemptId));
+ if (paymentInfo == null || !PaymentStatus.Processed.equals(PaymentStatus.valueOf(paymentInfo.getStatus()))) {
+ paymentApi.createPaymentForPaymentAttempt(UUID.fromString(paymentAttemptId));
}
}
}
diff --git a/payment/src/main/java/com/ning/billing/payment/setup/PaymentModule.java b/payment/src/main/java/com/ning/billing/payment/setup/PaymentModule.java
index 85641ed..d3d9320 100644
--- a/payment/src/main/java/com/ning/billing/payment/setup/PaymentModule.java
+++ b/payment/src/main/java/com/ning/billing/payment/setup/PaymentModule.java
@@ -64,5 +64,6 @@ public class PaymentModule extends AbstractModule {
bind(PaymentService.class).to(DefaultPaymentService.class).asEagerSingleton();
installPaymentProviderPlugins(paymentConfig);
installPaymentDao();
+ installRetryEngine();
}
}
diff --git a/payment/src/test/java/com/ning/billing/payment/provider/MockPaymentProviderPlugin.java b/payment/src/test/java/com/ning/billing/payment/provider/MockPaymentProviderPlugin.java
index 375bcfd..7155d63 100644
--- a/payment/src/test/java/com/ning/billing/payment/provider/MockPaymentProviderPlugin.java
+++ b/payment/src/test/java/com/ning/billing/payment/provider/MockPaymentProviderPlugin.java
@@ -22,6 +22,7 @@ import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.atomic.AtomicBoolean;
import org.apache.commons.lang.RandomStringUtils;
import org.joda.time.DateTime;
@@ -39,24 +40,34 @@ import com.ning.billing.payment.api.PaymentProviderAccount;
import com.ning.billing.payment.api.PaypalPaymentMethodInfo;
public class MockPaymentProviderPlugin implements PaymentProviderPlugin {
+ private final AtomicBoolean makeNextInvoiceFail = new AtomicBoolean(false);
private final Map<String, PaymentInfo> payments = new ConcurrentHashMap<String, PaymentInfo>();
private final Map<String, PaymentProviderAccount> accounts = new ConcurrentHashMap<String, PaymentProviderAccount>();
private final Map<String, PaymentMethodInfo> paymentMethods = new ConcurrentHashMap<String, PaymentMethodInfo>();
+ public void makeNextInvoiceFail() {
+ makeNextInvoiceFail.set(true);
+ }
+
@Override
public Either<PaymentError, PaymentInfo> processInvoice(Account account, Invoice invoice) {
- PaymentInfo payment = new PaymentInfo.Builder().setPaymentId(UUID.randomUUID().toString())
- .setAmount(invoice.getBalance())
- .setStatus("Processed")
- .setBankIdentificationNumber("1234")
- .setCreatedDate(new DateTime())
- .setEffectiveDate(new DateTime())
- .setPaymentNumber("12345")
- .setReferenceId("12345")
- .setType("Electronic")
- .build();
- payments.put(payment.getPaymentId(), payment);
- return Either.right(payment);
+ if (makeNextInvoiceFail.getAndSet(false)) {
+ return Either.left(new PaymentError("unknown", "test error"));
+ }
+ else {
+ PaymentInfo payment = new PaymentInfo.Builder().setPaymentId(UUID.randomUUID().toString())
+ .setAmount(invoice.getBalance())
+ .setStatus("Processed")
+ .setBankIdentificationNumber("1234")
+ .setCreatedDate(new DateTime())
+ .setEffectiveDate(new DateTime())
+ .setPaymentNumber("12345")
+ .setReferenceId("12345")
+ .setType("Electronic")
+ .build();
+ payments.put(payment.getPaymentId(), payment);
+ return Either.right(payment);
+ }
}
@Override
diff --git a/payment/src/test/java/com/ning/billing/payment/setup/PaymentTestModuleWithMocks.java b/payment/src/test/java/com/ning/billing/payment/setup/PaymentTestModuleWithMocks.java
index 3dfc637..c8f79bc 100644
--- a/payment/src/test/java/com/ning/billing/payment/setup/PaymentTestModuleWithMocks.java
+++ b/payment/src/test/java/com/ning/billing/payment/setup/PaymentTestModuleWithMocks.java
@@ -31,6 +31,8 @@ import com.ning.billing.payment.dao.PaymentDao;
import com.ning.billing.payment.provider.MockPaymentProviderPluginModule;
import com.ning.billing.util.bus.Bus;
import com.ning.billing.util.bus.InMemoryBus;
+import com.ning.billing.util.notificationq.MockNotificationQueueService;
+import com.ning.billing.util.notificationq.NotificationQueueService;
public class PaymentTestModuleWithMocks extends PaymentModule {
public static class MockProvider implements Provider<EntitlementBillingApi> {
@@ -38,12 +40,13 @@ public class PaymentTestModuleWithMocks extends PaymentModule {
public EntitlementBillingApi get() {
return BrainDeadProxyFactory.createBrainDeadProxyFor(EntitlementBillingApi.class);
}
-
+
}
-
-
+
+
public PaymentTestModuleWithMocks() {
- super(MapUtils.toProperties(ImmutableMap.of("killbill.payment.provider.default", "my-mock")));
+ super(MapUtils.toProperties(ImmutableMap.of("killbill.payment.provider.default", "my-mock",
+ "killbill.payment.engine.events.off", "false")));
}
@Override
@@ -65,5 +68,6 @@ public class PaymentTestModuleWithMocks extends PaymentModule {
bind(MockInvoiceDao.class).asEagerSingleton();
bind(InvoiceDao.class).to(MockInvoiceDao.class);
bind(EntitlementBillingApi.class).toProvider( MockProvider.class );
+ bind(NotificationQueueService.class).to(MockNotificationQueueService.class).asEagerSingleton();
}
}
diff --git a/payment/src/test/java/com/ning/billing/payment/TestRetryService.java b/payment/src/test/java/com/ning/billing/payment/TestRetryService.java
new file mode 100644
index 0000000..9930a3f
--- /dev/null
+++ b/payment/src/test/java/com/ning/billing/payment/TestRetryService.java
@@ -0,0 +1,177 @@
+package com.ning.billing.payment;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertTrue;
+
+import java.math.BigDecimal;
+import java.util.Arrays;
+import java.util.List;
+import java.util.UUID;
+
+import org.joda.time.DateTime;
+import org.joda.time.DateTimeZone;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Guice;
+import org.testng.annotations.Test;
+
+import com.google.inject.Inject;
+import com.ning.billing.account.api.Account;
+import com.ning.billing.account.glue.AccountModuleWithMocks;
+import com.ning.billing.catalog.api.Currency;
+import com.ning.billing.invoice.api.Invoice;
+import com.ning.billing.invoice.glue.InvoiceModuleWithMocks;
+import com.ning.billing.invoice.model.RecurringInvoiceItem;
+import com.ning.billing.payment.api.Either;
+import com.ning.billing.payment.api.PaymentApi;
+import com.ning.billing.payment.api.PaymentAttempt;
+import com.ning.billing.payment.api.PaymentError;
+import com.ning.billing.payment.api.PaymentInfo;
+import com.ning.billing.payment.api.PaymentStatus;
+import com.ning.billing.payment.dao.PaymentDao;
+import com.ning.billing.payment.provider.MockPaymentProviderPlugin;
+import com.ning.billing.payment.provider.PaymentProviderPluginRegistry;
+import com.ning.billing.payment.setup.PaymentConfig;
+import com.ning.billing.payment.setup.PaymentTestModuleWithMocks;
+import com.ning.billing.util.bus.Bus;
+import com.ning.billing.util.notificationq.MockNotificationQueue;
+import com.ning.billing.util.notificationq.Notification;
+import com.ning.billing.util.notificationq.NotificationQueueService;
+
+@Guice(modules = { PaymentTestModuleWithMocks.class, AccountModuleWithMocks.class, InvoiceModuleWithMocks.class })
+@Test(groups = "fast")
+public class TestRetryService {
+ @Inject
+ private PaymentConfig paymentConfig;
+ @Inject
+ private Bus eventBus;
+ @Inject
+ private PaymentApi paymentApi;
+ @Inject
+ private TestHelper testHelper;
+ @Inject
+ private PaymentProviderPluginRegistry registry;
+ @Inject
+ private PaymentDao paymentDao;
+ @Inject
+ private RetryService retryService;
+ @Inject
+ private NotificationQueueService notificationQueueService;
+
+ private MockPaymentProviderPlugin mockPaymentProviderPlugin;
+ private MockNotificationQueue mockNotificationQueue;
+
+ @BeforeClass(alwaysRun = true)
+ public void initialize() throws Exception {
+ retryService.initialize();
+ }
+
+ @BeforeMethod(alwaysRun = true)
+ public void setUp() throws Exception {
+ eventBus.start();
+ retryService.start();
+
+ mockPaymentProviderPlugin = (MockPaymentProviderPlugin)registry.getPlugin(null);
+ mockNotificationQueue = (MockNotificationQueue)notificationQueueService.getNotificationQueue(RetryService.SERVICE_NAME, RetryService.QUEUE_NAME);
+ }
+
+ @AfterMethod(alwaysRun = true)
+ public void tearDown() throws Exception {
+ retryService.stop();
+ eventBus.stop();
+ }
+
+ @Test
+ public void testSchedulesRetry() throws Exception {
+ final DateTime now = new DateTime(DateTimeZone.UTC);
+ final Account account = testHelper.createTestCreditCardAccount();
+ final Invoice invoice = testHelper.createTestInvoice(account, now, Currency.USD);
+ final BigDecimal amount = new BigDecimal("10.00");
+ final UUID subscriptionId = UUID.randomUUID();
+
+ invoice.addInvoiceItem(new RecurringInvoiceItem(invoice.getId(),
+ subscriptionId,
+ "test plan", "test phase",
+ now,
+ now.plusMonths(1),
+ amount,
+ new BigDecimal("1.0"),
+ Currency.USD));
+
+ mockPaymentProviderPlugin.makeNextInvoiceFail();
+
+ List<Either<PaymentError, PaymentInfo>> results = paymentApi.createPayment(account.getExternalKey(), Arrays.asList(invoice.getId().toString()));
+
+ assertEquals(results.size(), 1);
+ assertTrue(results.get(0).isLeft());
+
+ List<Notification> pendingNotifications = mockNotificationQueue.getPendingEvents();
+
+ assertEquals(pendingNotifications.size(), 1);
+
+ Notification notification = pendingNotifications.get(0);
+ PaymentAttempt paymentAttempt = paymentApi.getPaymentAttemptForInvoiceId(invoice.getId().toString());
+
+ assertNotNull(paymentAttempt);
+ assertEquals(notification.getNotificationKey(), paymentAttempt.getPaymentAttemptId().toString());
+ assertEquals(paymentAttempt.getRetryCount(), new Integer(1));
+
+ DateTime expectedRetryDate = paymentAttempt.getPaymentAttemptDate().plusDays(paymentConfig.getPaymentRetryDays().get(0));
+
+ assertEquals(notification.getEffectiveDate(), expectedRetryDate);
+ assertEquals(paymentAttempt.getNextRetryDate(), expectedRetryDate);
+ }
+
+ @Test
+ public void testRetries() throws Exception {
+ final DateTime now = new DateTime(DateTimeZone.UTC);
+ final Account account = testHelper.createTestCreditCardAccount();
+ final Invoice invoice = testHelper.createTestInvoice(account, now, Currency.USD);
+ final BigDecimal amount = new BigDecimal("10.00");
+ final UUID subscriptionId = UUID.randomUUID();
+
+ invoice.addInvoiceItem(new RecurringInvoiceItem(invoice.getId(),
+ subscriptionId,
+ "test plan", "test phase",
+ now,
+ now.plusMonths(1),
+ amount,
+ new BigDecimal("1.0"),
+ Currency.USD));
+
+ DateTime nextRetryDate = new DateTime(DateTimeZone.UTC).minusDays(1);
+ DateTime paymentAttemptDate = nextRetryDate.minusDays(paymentConfig.getPaymentRetryDays().get(0));
+ PaymentAttempt paymentAttempt = new PaymentAttempt(UUID.randomUUID(), invoice).cloner()
+ .setRetryCount(1)
+ .setPaymentAttemptDate(paymentAttemptDate)
+ .setNextRetryDate(nextRetryDate)
+ .build();
+
+ paymentDao.createPaymentAttempt(paymentAttempt);
+ retryService.scheduleRetry(paymentAttempt, nextRetryDate);
+
+ // wait a little to give the queue time to process
+ Thread.sleep(paymentConfig.getNotificationSleepTimeMs() * 2);
+
+ List<Notification> pendingNotifications = mockNotificationQueue.getPendingEvents();
+
+ assertEquals(pendingNotifications.size(), 0);
+
+ List<PaymentInfo> paymentInfos = paymentApi.getPaymentInfo(Arrays.asList(invoice.getId().toString()));
+
+ assertEquals(paymentInfos.size(), 1);
+
+ PaymentInfo paymentInfo = paymentInfos.get(0);
+
+ assertEquals(paymentInfo.getStatus(), PaymentStatus.Processed.toString());
+
+ PaymentAttempt updatedAttempt = paymentApi.getPaymentAttemptForInvoiceId(invoice.getId().toString());
+
+ assertEquals(updatedAttempt.getPaymentAttemptId(), paymentAttempt.getPaymentAttemptId());
+ assertEquals(paymentInfo.getPaymentId(), updatedAttempt.getPaymentId());
+
+ // TODO: what else to assert ?
+ }
+}
diff --git a/util/src/main/java/com/ning/billing/util/notificationq/DefaultNotificationQueue.java b/util/src/main/java/com/ning/billing/util/notificationq/DefaultNotificationQueue.java
index 8e2aaf8..c0c88fe 100644
--- a/util/src/main/java/com/ning/billing/util/notificationq/DefaultNotificationQueue.java
+++ b/util/src/main/java/com/ning/billing/util/notificationq/DefaultNotificationQueue.java
@@ -19,6 +19,7 @@ package com.ning.billing.util.notificationq;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
+
import org.joda.time.DateTime;
import org.skife.jdbi.v2.IDBI;
import org.skife.jdbi.v2.sqlobject.mixins.Transmogrifier;
@@ -64,6 +65,12 @@ public class DefaultNotificationQueue extends NotificationQueueBase {
}
@Override
+ public void recordFutureNotification(DateTime futureNotificationTime, NotificationKey notificationKey) {
+ Notification notification = new DefaultNotification(getFullQName(), notificationKey.toString(), futureNotificationTime);
+ dao.insertNotification(notification);
+ }
+
+ @Override
public void recordFutureNotificationFromTransaction(final Transmogrifier transactionalDao,
final DateTime futureNotificationTime, final NotificationKey notificationKey) {
NotificationSqlDao transactionalNotificationDao = transactionalDao.become(NotificationSqlDao.class);
diff --git a/util/src/main/java/com/ning/billing/util/notificationq/NotificationQueue.java b/util/src/main/java/com/ning/billing/util/notificationq/NotificationQueue.java
index e1dcdbf..fb88d4c 100644
--- a/util/src/main/java/com/ning/billing/util/notificationq/NotificationQueue.java
+++ b/util/src/main/java/com/ning/billing/util/notificationq/NotificationQueue.java
@@ -23,9 +23,18 @@ import com.ning.billing.util.notificationq.NotificationQueueService.Notification
public interface NotificationQueue {
- /**
+ /**
+ *
+ * Record the need to be called back when the notification is ready
+ *
+ * @param futureNotificationTime the time at which the notification is ready
+ * @param notificationKey the key for that notification
+ */
+ public void recordFutureNotification(final DateTime futureNotificationTime, final NotificationKey notificationKey);
+
+ /**
*
- * Record from within a transaction the need to be called back when the notification is ready
+ * Record from within a transaction the need to be called back when the notification is ready
*
* @param transactionalDao the transactionalDao
* @param futureNotificationTime the time at which the notification is ready
diff --git a/util/src/test/java/com/ning/billing/util/notificationq/MockNotificationQueue.java b/util/src/test/java/com/ning/billing/util/notificationq/MockNotificationQueue.java
index e96d2cf..b76a8ad 100644
--- a/util/src/test/java/com/ning/billing/util/notificationq/MockNotificationQueue.java
+++ b/util/src/test/java/com/ning/billing/util/notificationq/MockNotificationQueue.java
@@ -49,9 +49,7 @@ public class MockNotificationQueue extends NotificationQueueBase implements Noti
}
@Override
- public void recordFutureNotificationFromTransaction(
- Transmogrifier transactionalDao, DateTime futureNotificationTime,
- NotificationKey notificationKey) {
+ public void recordFutureNotification(DateTime futureNotificationTime, NotificationKey notificationKey) {
Notification notification = new DefaultNotification("MockQueue", notificationKey.toString(), futureNotificationTime);
synchronized(notifications) {
notifications.add(notification);
@@ -59,6 +57,24 @@ public class MockNotificationQueue extends NotificationQueueBase implements Noti
}
@Override
+ public void recordFutureNotificationFromTransaction(
+ Transmogrifier transactionalDao, DateTime futureNotificationTime,
+ NotificationKey notificationKey) {
+ recordFutureNotification(futureNotificationTime, notificationKey);
+ }
+
+ public List<Notification> getPendingEvents() {
+ List<Notification> result = new ArrayList<Notification>();
+
+ for (Notification notification : notifications) {
+ if (notification.getProcessingState() == NotificationLifecycleState.AVAILABLE) {
+ result.add(notification);
+ }
+ }
+ return result;
+ }
+
+ @Override
protected int doProcessEvents(int sequenceId) {
int result = 0;