killbill-aplcache
Changes
beatrix/src/test/java/com/ning/billing/beatrix/integration/payment/MockPaymentInfoReceiver.java 53(+0 -53)
beatrix/src/test/java/com/ning/billing/beatrix/integration/payment/PaymentTestModule.java 68(+0 -68)
beatrix/src/test/java/com/ning/billing/beatrix/integration/payment/TestPaymentInvoiceIntegration.java 169(+0 -169)
Details
diff --git a/api/src/main/java/com/ning/billing/payment/plugin/api/PaymentInfoPlugin.java b/api/src/main/java/com/ning/billing/payment/plugin/api/PaymentInfoPlugin.java
index 344d1c0..aac15fa 100644
--- a/api/src/main/java/com/ning/billing/payment/plugin/api/PaymentInfoPlugin.java
+++ b/api/src/main/java/com/ning/billing/payment/plugin/api/PaymentInfoPlugin.java
@@ -36,24 +36,4 @@ public interface PaymentInfoPlugin {
public PaymentPluginStatus getStatus();
public String getError();
-
-
- /**
- * STEPH
-
- * Zuora specific
-
- public String getExternalPaymentId();
-
- public String getReferenceId();
-
- public String getPaymentMethodId();
-
- public String getPaymentNumber();
-
- public String getStatus();
-
- public String getType();
- *
- */
}
diff --git a/api/src/main/java/com/ning/billing/payment/plugin/api/PaymentProviderPlugin.java b/api/src/main/java/com/ning/billing/payment/plugin/api/PaymentProviderPlugin.java
index 1e3b205..cf4ee46 100644
--- a/api/src/main/java/com/ning/billing/payment/plugin/api/PaymentProviderPlugin.java
+++ b/api/src/main/java/com/ning/billing/payment/plugin/api/PaymentProviderPlugin.java
@@ -16,22 +16,22 @@
package com.ning.billing.payment.plugin.api;
+import java.math.BigDecimal;
import java.util.List;
import java.util.UUID;
import com.ning.billing.account.api.Account;
-import com.ning.billing.invoice.api.Invoice;
import com.ning.billing.payment.api.PaymentMethodInfo;
public interface PaymentProviderPlugin {
- public PaymentInfoPlugin processInvoice(Account account, Invoice invoice)
+ public PaymentInfoPlugin processPayment(String externalAccountKey, UUID paymentId, BigDecimal amount)
throws PaymentPluginApiException;
public String createPaymentProviderAccount(Account account)
throws PaymentPluginApiException;
- public PaymentInfoPlugin getPaymentInfo(String paymentId)
+ public PaymentInfoPlugin getPaymentInfo(UUID paymentId)
throws PaymentPluginApiException;
public PaymentProviderAccount getPaymentProviderAccount(String accountKey)
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/JaxrsResource.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/JaxrsResource.java
index d970921..f334d77 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/JaxrsResource.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/JaxrsResource.java
@@ -15,12 +15,6 @@
*/
package com.ning.billing.jaxrs.resources;
-import com.ning.billing.jaxrs.json.CustomFieldJson;
-import com.ning.billing.util.callcontext.CallContext;
-
-import javax.ws.rs.core.Response;
-import java.util.List;
-import java.util.UUID;
public interface JaxrsResource {
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/PaymentResource.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/PaymentResource.java
index 538c2bd..9f8d421 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/PaymentResource.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/PaymentResource.java
@@ -43,8 +43,9 @@ import com.ning.billing.util.dao.ObjectType;
import java.util.List;
import java.util.UUID;
-@Path(JaxrsResource.INVOICES_PATH)
+@Path(JaxrsResource.PAYMENTS_PATH)
public class PaymentResource extends JaxRsResourceBase {
+
private static final String ID_PARAM_NAME = "paymentId";
private static final String CUSTOM_FIELD_URI = JaxrsResource.CUSTOM_FIELDS + "/{" + ID_PARAM_NAME + ":" + UUID_PATTERN + "}";
private static final String TAG_URI = JaxrsResource.TAGS + "/{" + ID_PARAM_NAME + ":" + UUID_PATTERN + "}";
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 4c66cae..195cfea 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
@@ -43,7 +43,7 @@ public class DefaultPaymentApi implements PaymentApi {
final RefundProcessor refundProcessor) {
this.methodProcessor = methodProcessor;
this.accountProcessor = accountProcessor;
- this.paymentProcessor = null;
+ this.paymentProcessor = paymentProcessor;
this.refundProcessor = refundProcessor;
}
@@ -134,7 +134,6 @@ public class DefaultPaymentApi implements PaymentApi {
@Override
public PaymentProviderAccount getPaymentProviderAccount(String accountKey)
throws PaymentApiException {
- // TODO Auto-generated method stub
- return null;
+ return accountProcessor.getPaymentProviderAccount(accountKey);
}
}
diff --git a/payment/src/main/java/com/ning/billing/payment/core/PaymentProcessor.java b/payment/src/main/java/com/ning/billing/payment/core/PaymentProcessor.java
index ba64c3d..ed945fe 100644
--- a/payment/src/main/java/com/ning/billing/payment/core/PaymentProcessor.java
+++ b/payment/src/main/java/com/ning/billing/payment/core/PaymentProcessor.java
@@ -16,6 +16,7 @@
package com.ning.billing.payment.core;
import java.math.BigDecimal;
+import java.math.RoundingMode;
import java.util.LinkedList;
import java.util.List;
import java.util.UUID;
@@ -47,22 +48,25 @@ import com.ning.billing.payment.plugin.api.PaymentPluginApiException;
import com.ning.billing.payment.plugin.api.PaymentProviderPlugin;
import com.ning.billing.payment.plugin.api.PaymentInfoPlugin.PaymentPluginStatus;
import com.ning.billing.payment.provider.PaymentProviderPluginRegistry;
-import com.ning.billing.payment.retry.FailedPaymentRetryService;
+import com.ning.billing.payment.retry.FailedPaymentRetryService.FailedPaymentRetryServiceScheduler;
import com.ning.billing.util.bus.Bus;
import com.ning.billing.util.bus.BusEvent;
import com.ning.billing.util.callcontext.CallContext;
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.globallocker.GlobalLocker;
public class PaymentProcessor extends ProcessorBase {
private final InvoicePaymentApi invoicePaymentApi;
- private final FailedPaymentRetryService retryService;
+ private final FailedPaymentRetryServiceScheduler retryService;
private final PaymentConfig config;
private final PaymentDao paymentDao;
private final CallContextFactory factory;
+ private final Clock clock;
+
private static final Logger log = LoggerFactory.getLogger(PaymentProcessor.class);
@@ -70,16 +74,18 @@ public class PaymentProcessor extends ProcessorBase {
public PaymentProcessor(final PaymentProviderPluginRegistry pluginRegistry,
final AccountUserApi accountUserApi,
final InvoicePaymentApi invoicePaymentApi,
- final FailedPaymentRetryService retryService,
+ final FailedPaymentRetryServiceScheduler retryService,
final PaymentDao paymentDao,
final PaymentConfig config,
final Bus eventBus,
+ final Clock clock,
final GlobalLocker locker,
final CallContextFactory factory) {
super(pluginRegistry, accountUserApi, eventBus, locker);
this.invoicePaymentApi = invoicePaymentApi;
this.retryService = retryService;
this.paymentDao = paymentDao;
+ this.clock = clock;
this.config = config;
this.factory = factory;
}
@@ -185,10 +191,8 @@ public class PaymentProcessor extends ProcessorBase {
private Payment processNewPaymentWithAccountLocked(PaymentProviderPlugin plugin, Account account, Invoice invoice,
CallContext context) throws PaymentApiException {
-
-
- PaymentModelDao payment = new PaymentModelDao(account.getId(), invoice.getId(), invoice.getTotalAmount(), invoice.getCurrency(), invoice.getTargetDate());
- PaymentAttemptModelDao attempt = new PaymentAttemptModelDao(account.getId(), invoice.getId(), payment.getId());
+ PaymentModelDao payment = new PaymentModelDao(account.getId(), invoice.getId(), invoice.getTotalAmount().setScale(2, RoundingMode.HALF_EVEN), invoice.getCurrency(), invoice.getTargetDate());
+ PaymentAttemptModelDao attempt = new PaymentAttemptModelDao(account.getId(), invoice.getId(), payment.getId(), clock.getUTCNow());
PaymentModelDao savedPayment = paymentDao.insertPaymentWithAttempt(payment, attempt, context);
return processPaymentWithAccountLocked(plugin, account, invoice, savedPayment, attempt, context);
@@ -197,28 +201,30 @@ public class PaymentProcessor extends ProcessorBase {
private Payment processRetryPaymentWithAccountLocked(PaymentProviderPlugin plugin, Account account, Invoice invoice, PaymentModelDao payment,
CallContext context) throws PaymentApiException {
- PaymentAttemptModelDao attempt = new PaymentAttemptModelDao(account.getId(), invoice.getId(), payment.getId());
+ PaymentAttemptModelDao attempt = new PaymentAttemptModelDao(account.getId(), invoice.getId(), payment.getId(), clock.getUTCNow());
paymentDao.insertNewAttemptForPayment(payment.getId(), attempt, context);
return processPaymentWithAccountLocked(plugin, account, invoice, payment, attempt, context);
}
private Payment processPaymentWithAccountLocked(PaymentProviderPlugin plugin, Account account, Invoice invoice,
- PaymentModelDao payment, PaymentAttemptModelDao attemptInput, CallContext context) throws PaymentApiException {
-
+ PaymentModelDao paymentInput, PaymentAttemptModelDao attemptInput, CallContext context) throws PaymentApiException {
+
BusEvent event = null;
List<PaymentAttemptModelDao> allAttempts = null;
PaymentAttemptModelDao lastAttempt = null;
+ PaymentModelDao payment = null;
try {
- allAttempts = paymentDao.getAttemptsForPayment(payment.getId());
- lastAttempt = allAttempts.get(allAttempts.size() - 1);
-
- PaymentInfoPlugin paymentPluginInfo = plugin.processInvoice(account, invoice);
+ PaymentInfoPlugin paymentPluginInfo = plugin.processPayment(account.getExternalKey(), paymentInput.getId(), paymentInput.getAmount());
+
// STEPH check if plugin returns UNKNOWN (exception from plugin)
PaymentStatus paymentStatus = paymentPluginInfo.getStatus() == PaymentPluginStatus.ERROR ? PaymentStatus.ERROR : PaymentStatus.SUCCESS;
- paymentDao.updateStatusForPaymentWithAttempt(payment.getId(), paymentStatus, paymentPluginInfo.getError(), attemptInput.getId(), context);
-
+ paymentDao.updateStatusForPaymentWithAttempt(paymentInput.getId(), paymentStatus, paymentPluginInfo.getError(), attemptInput.getId(), context);
+
+ allAttempts = paymentDao.getAttemptsForPayment(paymentInput.getId());
+ lastAttempt = allAttempts.get(allAttempts.size() - 1);
+ payment = paymentDao.getPayment(paymentInput.getId());
invoicePaymentApi.notifyOfPaymentAttempt(invoice.getId(),
paymentStatus == PaymentStatus.SUCCESS ? payment.getAmount() : null,
@@ -231,16 +237,20 @@ public class PaymentProcessor extends ProcessorBase {
invoice.getId(), payment.getId(), payment.getAmount(), payment.getPaymentNumber(), paymentStatus, context.getUserToken(), payment.getEffectiveDate());
} catch (PaymentPluginApiException e) {
+
+ allAttempts = paymentDao.getAttemptsForPayment(paymentInput.getId());
+ lastAttempt = allAttempts.get(allAttempts.size() - 1);
+
log.info(String.format("Could not process payment for account %s, invoice %s, error = %s",
account.getId(), invoice.getId(), e.getMessage()));
- scheduleRetry(payment.getId(), lastAttempt.getEffectiveDate(), allAttempts.size());
- event = new DefaultPaymentErrorEvent(account.getId(), invoice.getId(), payment.getId(), e.getErrorMessage(), context.getUserToken());
+ scheduleRetry(paymentInput.getId(), lastAttempt.getEffectiveDate(), allAttempts.size());
+ event = new DefaultPaymentErrorEvent(account.getId(), invoice.getId(), paymentInput.getId(), e.getErrorMessage(), context.getUserToken());
throw new PaymentApiException(e, ErrorCode.PAYMENT_CREATE_PAYMENT, account.getId(), e.getMessage());
} finally {
postPaymentEvent(event, account.getId());
}
- return null;
+ return new DefaultPayment(payment, allAttempts);
}
private void scheduleRetry(final UUID paymentId, final DateTime lastAttemptDate, final int numberAttempts) {
diff --git a/payment/src/main/java/com/ning/billing/payment/dao/AuditedPaymentDao.java b/payment/src/main/java/com/ning/billing/payment/dao/AuditedPaymentDao.java
index 7dde65f..a98b067 100644
--- a/payment/src/main/java/com/ning/billing/payment/dao/AuditedPaymentDao.java
+++ b/payment/src/main/java/com/ning/billing/payment/dao/AuditedPaymentDao.java
@@ -132,12 +132,24 @@ public class AuditedPaymentDao implements PaymentDao {
private void updatePaymentStatusFromTransaction(final UUID paymentId, final PaymentStatus paymentStatus, final CallContext context, final PaymentSqlDao transactional) {
transactional.updatePaymentStatus(paymentId.toString(), paymentStatus.toString(), context);
- // STEPH check with Jeff
+ PaymentModelDao savedPayment = transactional.getPayment(paymentId.toString());
+ Long recordId = transactional.getRecordId(savedPayment.getId().toString());
+ EntityHistory<PaymentModelDao> history = new EntityHistory<PaymentModelDao>(savedPayment.getId(), recordId, savedPayment, ChangeType.UPDATE);
+ transactional.insertHistoryFromTransaction(history, context);
+ Long historyRecordId = transactional.getHistoryRecordId(recordId);
+ EntityAudit audit = new EntityAudit(TableName.PAYMENTS, historyRecordId, ChangeType.UPDATE);
+ transactional.insertAuditFromTransaction(audit, context);
}
private void updatePaymentAttemptStatusFromTransaction(final UUID attemptId, final PaymentStatus processingStatus, final String paymentError, final CallContext context, final PaymentAttemptSqlDao transactional) {
transactional.updatePaymentAttemptStatus(attemptId.toString(), processingStatus.toString(), paymentError);
- //STEPH check with Jeff
+ PaymentAttemptModelDao savedAttempt = transactional.getPaymentAttempt(attemptId.toString());
+ Long recordId = transactional.getRecordId(savedAttempt.getId().toString());
+ EntityHistory<PaymentAttemptModelDao> history = new EntityHistory<PaymentAttemptModelDao>(savedAttempt.getId(), recordId, savedAttempt, ChangeType.UPDATE);
+ transactional.insertHistoryFromTransaction(history, context);
+ Long historyRecordId = transactional.getHistoryRecordId(recordId);
+ EntityAudit audit = new EntityAudit(TableName.PAYMENT_ATTEMPTS, historyRecordId, ChangeType.UPDATE);
+ transactional.insertAuditFromTransaction(audit, context);
}
@Override
diff --git a/payment/src/main/java/com/ning/billing/payment/dao/PaymentAttemptModelDao.java b/payment/src/main/java/com/ning/billing/payment/dao/PaymentAttemptModelDao.java
index f80edd1..25254be 100644
--- a/payment/src/main/java/com/ning/billing/payment/dao/PaymentAttemptModelDao.java
+++ b/payment/src/main/java/com/ning/billing/payment/dao/PaymentAttemptModelDao.java
@@ -42,8 +42,8 @@ public class PaymentAttemptModelDao extends EntityBase {
this.paymentError = paymentError;
}
- public PaymentAttemptModelDao(UUID accountId, UUID invoiceId, UUID paymentId) {
- this(UUID.randomUUID(), accountId, invoiceId, paymentId, PaymentStatus.UNKNOWN, null, null);
+ public PaymentAttemptModelDao(UUID accountId, UUID invoiceId, UUID paymentId, DateTime effectiveDate) {
+ this(UUID.randomUUID(), accountId, invoiceId, paymentId, PaymentStatus.UNKNOWN, effectiveDate, null);
}
public PaymentAttemptModelDao(PaymentAttemptModelDao src, PaymentStatus newProcessingStatus, String paymentError) {
diff --git a/payment/src/main/java/com/ning/billing/payment/dao/PaymentModelDao.java b/payment/src/main/java/com/ning/billing/payment/dao/PaymentModelDao.java
index 396a2dd..1511ca8 100644
--- a/payment/src/main/java/com/ning/billing/payment/dao/PaymentModelDao.java
+++ b/payment/src/main/java/com/ning/billing/payment/dao/PaymentModelDao.java
@@ -27,7 +27,7 @@ import com.ning.billing.util.entity.EntityBase;
public class PaymentModelDao extends EntityBase {
- private final static Integer INVALID_PAYMENT_NUMBER = new Integer(-13);
+ public final static Integer INVALID_PAYMENT_NUMBER = new Integer(-13);
private final UUID accountId;
private final UUID invoiceId;
diff --git a/payment/src/main/java/com/ning/billing/payment/glue/DefaultPaymentService.java b/payment/src/main/java/com/ning/billing/payment/glue/DefaultPaymentService.java
index 28740a4..6fdb703 100644
--- a/payment/src/main/java/com/ning/billing/payment/glue/DefaultPaymentService.java
+++ b/payment/src/main/java/com/ning/billing/payment/glue/DefaultPaymentService.java
@@ -32,9 +32,11 @@ import com.ning.billing.util.notificationq.NotificationQueueService.NoSuchNotifi
import com.ning.billing.util.notificationq.NotificationQueueService.NotificationQueueAlreadyExists;
public class DefaultPaymentService implements PaymentService {
+
private static final Logger log = LoggerFactory.getLogger(DefaultPaymentService.class);
- private static final String SERVICE_NAME = "payment-service";
+ // STEPH for retry crappiness
+ public static final String SERVICE_NAME = "payment-service";
private final RequestProcessor requestProcessor;
private final Bus eventBus;
diff --git a/payment/src/main/java/com/ning/billing/payment/glue/PaymentModule.java b/payment/src/main/java/com/ning/billing/payment/glue/PaymentModule.java
index 877531d..4056f99 100644
--- a/payment/src/main/java/com/ning/billing/payment/glue/PaymentModule.java
+++ b/payment/src/main/java/com/ning/billing/payment/glue/PaymentModule.java
@@ -35,6 +35,8 @@ import com.ning.billing.payment.dao.PaymentDao;
import com.ning.billing.payment.provider.DefaultPaymentProviderPluginRegistry;
import com.ning.billing.payment.provider.PaymentProviderPluginRegistry;
import com.ning.billing.payment.retry.FailedPaymentRetryService;
+import com.ning.billing.payment.retry.FailedPaymentRetryService.FailedPaymentRetryServiceScheduler;
+import com.ning.billing.payment.retry.TimedoutPaymentRetryService;
public class PaymentModule extends AbstractModule {
private final Properties props;
@@ -54,8 +56,17 @@ public class PaymentModule extends AbstractModule {
protected void installPaymentProviderPlugins(PaymentConfig config) {
}
- protected void installRetryEngine() {
+ protected void installRetryEngines() {
bind(FailedPaymentRetryService.class).asEagerSingleton();
+ bind(TimedoutPaymentRetryService.class).asEagerSingleton();
+ bind(FailedPaymentRetryServiceScheduler.class).asEagerSingleton();
+ }
+
+ protected void installProcessors() {
+ bind(AccountProcessor.class).asEagerSingleton();
+ bind(PaymentProcessor.class).asEagerSingleton();
+ bind(RefundProcessor.class).asEagerSingleton();
+ bind(PaymentMethodProcessor.class).asEagerSingleton();
}
@Override
@@ -68,12 +79,9 @@ public class PaymentModule extends AbstractModule {
bind(PaymentApi.class).to(DefaultPaymentApi.class).asEagerSingleton();
bind(RequestProcessor.class).asEagerSingleton();
bind(PaymentService.class).to(DefaultPaymentService.class).asEagerSingleton();
- bind(AccountProcessor.class).asEagerSingleton();
- bind(PaymentProcessor.class).asEagerSingleton();
- bind(RefundProcessor.class).asEagerSingleton();
- bind(PaymentMethodProcessor.class).asEagerSingleton();
installPaymentProviderPlugins(paymentConfig);
installPaymentDao();
- installRetryEngine();
+ installProcessors();
+ installRetryEngines();
}
}
diff --git a/payment/src/main/java/com/ning/billing/payment/provider/NoOpPaymentProviderPlugin.java b/payment/src/main/java/com/ning/billing/payment/provider/NoOpPaymentProviderPlugin.java
index 9f2c49b..98ca014 100644
--- a/payment/src/main/java/com/ning/billing/payment/provider/NoOpPaymentProviderPlugin.java
+++ b/payment/src/main/java/com/ning/billing/payment/provider/NoOpPaymentProviderPlugin.java
@@ -25,6 +25,7 @@ import org.joda.time.DateTimeZone;
import com.ning.billing.account.api.Account;
import com.ning.billing.invoice.api.Invoice;
+import com.ning.billing.payment.api.Payment;
import com.ning.billing.payment.api.PaymentMethodInfo;
import com.ning.billing.payment.plugin.api.PaymentInfoPlugin;
import com.ning.billing.payment.plugin.api.PaymentPluginApiException;
@@ -44,9 +45,9 @@ public class NoOpPaymentProviderPlugin implements PaymentProviderPlugin {
}
@Override
- public PaymentInfoPlugin processInvoice(final Account account, final Invoice invoice)
+ public PaymentInfoPlugin processPayment(final String externalAccountKey, final UUID paymentId, final BigDecimal amount)
throws PaymentPluginApiException {
- PaymentInfoPlugin payment = new PaymentInfoPlugin() {
+ PaymentInfoPlugin paymentResult = new PaymentInfoPlugin() {
@Override
public DateTime getEffectiveDate() {
@@ -58,7 +59,7 @@ public class NoOpPaymentProviderPlugin implements PaymentProviderPlugin {
}
@Override
public BigDecimal getAmount() {
- return invoice.getBalance();
+ return amount;
}
@Override
public PaymentPluginStatus getStatus() {
@@ -69,7 +70,7 @@ public class NoOpPaymentProviderPlugin implements PaymentProviderPlugin {
return null;
}
};
- return payment;
+ return paymentResult;
}
@Override
@@ -80,7 +81,7 @@ public class NoOpPaymentProviderPlugin implements PaymentProviderPlugin {
}
@Override
- public PaymentInfoPlugin getPaymentInfo(String paymentId)
+ public PaymentInfoPlugin getPaymentInfo(UUID paymentId)
throws PaymentPluginApiException {
return null;
diff --git a/payment/src/main/java/com/ning/billing/payment/retry/FailedPaymentRetryService.java b/payment/src/main/java/com/ning/billing/payment/retry/FailedPaymentRetryService.java
index 3e9e718..5cb6c4d 100644
--- a/payment/src/main/java/com/ning/billing/payment/retry/FailedPaymentRetryService.java
+++ b/payment/src/main/java/com/ning/billing/payment/retry/FailedPaymentRetryService.java
@@ -29,17 +29,11 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.inject.Inject;
-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.config.PaymentConfig;
-import com.ning.billing.payment.api.Payment.PaymentAttempt;
-import com.ning.billing.payment.api.PaymentApi;
-import com.ning.billing.payment.api.PaymentApiException;
-import com.ning.billing.payment.api.PaymentInfoEvent;
import com.ning.billing.payment.core.PaymentProcessor;
-import com.ning.billing.payment.dao.PaymentAttemptModelDao;
import com.ning.billing.payment.dao.PaymentDao;
+import com.ning.billing.payment.glue.DefaultPaymentService;
import com.ning.billing.util.notificationq.NotificationKey;
@@ -100,20 +94,39 @@ public class FailedPaymentRetryService implements RetryService {
}
}
- public void scheduleRetry(final UUID paymentId, final DateTime timeOfRetry) {
-
- NotificationKey key = new NotificationKey() {
- @Override
- public String toString() {
- return paymentId.toString();
- }
- };
- if (retryQueue != null) {
- retryQueue.recordFutureNotification(timeOfRetry, key);
- }
- }
+
private void retry(final UUID paymentId, final CallContext context) {
paymentProcessor.retryPayment(paymentId);
}
+
+
+ public static class FailedPaymentRetryServiceScheduler {
+
+ private final NotificationQueueService notificationQueueService;
+
+ @Inject
+ public FailedPaymentRetryServiceScheduler(final NotificationQueueService notificationQueueService) {
+ this.notificationQueueService = notificationQueueService;
+ }
+
+
+ public void scheduleRetry(final UUID paymentId, final DateTime timeOfRetry) {
+
+ try {
+ NotificationQueue retryQueue = notificationQueueService.getNotificationQueue(DefaultPaymentService.SERVICE_NAME, QUEUE_NAME);
+ NotificationKey key = new NotificationKey() {
+ @Override
+ public String toString() {
+ return paymentId.toString();
+ }
+ };
+ if (retryQueue != null) {
+ retryQueue.recordFutureNotification(timeOfRetry, key);
+ }
+ } catch (NoSuchNotificationQueue e) {
+ log.error(String.format("Failed to retrieve notification queue %s:%s", DefaultPaymentService.SERVICE_NAME, QUEUE_NAME));
+ }
+ }
+ }
}
diff --git a/payment/src/main/java/com/ning/billing/payment/retry/TimedoutPaymentRetryService.java b/payment/src/main/java/com/ning/billing/payment/retry/TimedoutPaymentRetryService.java
index 9ea8107..d1cbf77 100644
--- a/payment/src/main/java/com/ning/billing/payment/retry/TimedoutPaymentRetryService.java
+++ b/payment/src/main/java/com/ning/billing/payment/retry/TimedoutPaymentRetryService.java
@@ -23,7 +23,6 @@ import org.slf4j.LoggerFactory;
import com.google.inject.Inject;
import com.ning.billing.config.PaymentConfig;
-import com.ning.billing.payment.api.PaymentApi;
import com.ning.billing.util.callcontext.CallContext;
import com.ning.billing.util.callcontext.CallOrigin;
import com.ning.billing.util.callcontext.DefaultCallContext;
@@ -46,17 +45,14 @@ public class TimedoutPaymentRetryService implements RetryService {
private final Clock clock;
private final NotificationQueueService notificationQueueService;
private final PaymentConfig config;
- private final PaymentApi paymentApi;
private NotificationQueue retryQueue;
@Inject
public TimedoutPaymentRetryService(Clock clock,
NotificationQueueService notificationQueueService,
- PaymentConfig config,
- PaymentApi paymentApi) {
+ PaymentConfig config) {
this.clock = clock;
this.notificationQueueService = notificationQueueService;
- this.paymentApi = paymentApi;
this.config = config;
}
diff --git a/payment/src/test/java/com/ning/billing/payment/api/TestPaymentApi.java b/payment/src/test/java/com/ning/billing/payment/api/TestPaymentApi.java
index 59849a0..62e76e4 100644
--- a/payment/src/test/java/com/ning/billing/payment/api/TestPaymentApi.java
+++ b/payment/src/test/java/com/ning/billing/payment/api/TestPaymentApi.java
@@ -17,14 +17,11 @@
package com.ning.billing.payment.api;
import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertTrue;
import java.math.BigDecimal;
import java.math.RoundingMode;
-import java.util.Arrays;
-import java.util.List;
import java.util.UUID;
import org.apache.commons.lang.RandomStringUtils;
@@ -32,6 +29,7 @@ import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Guice;
import org.testng.annotations.Test;
import com.google.inject.Inject;
@@ -41,9 +39,12 @@ import com.ning.billing.invoice.api.Invoice;
import com.ning.billing.invoice.api.InvoicePaymentApi;
import com.ning.billing.mock.BrainDeadProxyFactory;
import com.ning.billing.mock.BrainDeadProxyFactory.ZombieControl;
+import com.ning.billing.mock.glue.MockClockModule;
+import com.ning.billing.mock.glue.MockJunctionModule;
import com.ning.billing.payment.MockRecurringInvoiceItem;
import com.ning.billing.payment.TestHelper;
import com.ning.billing.payment.api.Payment.PaymentAttempt;
+import com.ning.billing.payment.glue.PaymentTestModuleWithMocks;
import com.ning.billing.payment.plugin.api.PaymentProviderAccount;
import com.ning.billing.util.bus.Bus;
import com.ning.billing.util.bus.Bus.EventBusException;
@@ -52,8 +53,11 @@ import com.ning.billing.util.callcontext.CallOrigin;
import com.ning.billing.util.callcontext.DefaultCallContext;
import com.ning.billing.util.callcontext.UserType;
import com.ning.billing.util.clock.Clock;
+import com.ning.billing.util.glue.CallContextModule;
-public abstract class TestPaymentApi {
+@Guice(modules = { PaymentTestModuleWithMocks.class, MockClockModule.class, MockJunctionModule.class, CallContextModule.class })
+@Test(groups = "fast")
+public class TestPaymentApi {
@Inject
private Bus eventBus;
@Inject
@@ -102,7 +106,7 @@ public abstract class TestPaymentApi {
new BigDecimal("1.0"),
Currency.USD));
- Payment paymentInfo = paymentApi.createPayment(account.getExternalKey(), invoice.getId(), context);
+ Payment paymentInfo = paymentApi.createPayment(account.getExternalKey(), invoice.getId(), context);
assertNotNull(paymentInfo.getId());
assertTrue(paymentInfo.getAmount().compareTo(amount.setScale(2, RoundingMode.HALF_EVEN)) == 0);
diff --git a/payment/src/test/java/com/ning/billing/payment/dao/TestPaymentDao.java b/payment/src/test/java/com/ning/billing/payment/dao/TestPaymentDao.java
index 899cc6f..e3b6a6c 100644
--- a/payment/src/test/java/com/ning/billing/payment/dao/TestPaymentDao.java
+++ b/payment/src/test/java/com/ning/billing/payment/dao/TestPaymentDao.java
@@ -26,6 +26,7 @@ import org.apache.commons.io.IOUtils;
import org.joda.time.DateTime;
import org.skife.config.ConfigurationObjectFactory;
import org.skife.jdbi.v2.IDBI;
+import org.testng.Assert;
import org.testng.annotations.AfterSuite;
import org.testng.annotations.BeforeSuite;
@@ -36,6 +37,8 @@ import com.ning.billing.catalog.api.Currency;
import com.ning.billing.dbi.DBIProvider;
import com.ning.billing.dbi.DbiConfig;
import com.ning.billing.dbi.MysqlTestingHelper;
+import com.ning.billing.payment.api.DefaultPayment;
+import com.ning.billing.payment.api.Payment;
import com.ning.billing.payment.api.PaymentStatus;
import com.ning.billing.util.callcontext.CallContext;
import com.ning.billing.util.callcontext.TestCallContext;
@@ -101,7 +104,7 @@ public class TestPaymentDao {
DateTime effectiveDate = clock.getUTCNow();
PaymentModelDao payment = new PaymentModelDao(accountId, invoiceId, amount, currency, effectiveDate);
- PaymentAttemptModelDao attempt = new PaymentAttemptModelDao(accountId, invoiceId, payment.getId());
+ PaymentAttemptModelDao attempt = new PaymentAttemptModelDao(accountId, invoiceId, payment.getId(), clock.getUTCNow());
PaymentModelDao savedPayment = paymentDao.insertPaymentWithAttempt(payment, attempt, context);
PaymentStatus paymentStatus = PaymentStatus.SUCCESS;
@@ -119,7 +122,7 @@ public class TestPaymentDao {
assertEquals(savedPayment.getAmount().compareTo(amount), 0);
assertEquals(savedPayment.getCurrency(), currency);
assertEquals(savedPayment.getEffectiveDate().compareTo(effectiveDate), 0);
- assertEquals(savedPayment.getPaymentNumber(), new Integer(1));
+ Assert.assertNotEquals(savedPayment.getPaymentNumber(), PaymentModelDao.INVALID_PAYMENT_NUMBER);
assertEquals(savedPayment.getPaymentStatus(), PaymentStatus.SUCCESS);
List<PaymentAttemptModelDao> attempts = paymentDao.getAttemptsForPayment(payment.getId());
@@ -143,7 +146,7 @@ public class TestPaymentDao {
DateTime effectiveDate = clock.getUTCNow();
PaymentModelDao payment = new PaymentModelDao(accountId, invoiceId, amount, currency, effectiveDate);
- PaymentAttemptModelDao attempt = new PaymentAttemptModelDao(accountId, invoiceId, payment.getId());
+ PaymentAttemptModelDao attempt = new PaymentAttemptModelDao(accountId, invoiceId, payment.getId(), clock.getUTCNow());
PaymentModelDao savedPayment = paymentDao.insertPaymentWithAttempt(payment, attempt, context);
assertEquals(savedPayment.getId(), payment.getId());
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 93fb8ed..4349993 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
@@ -16,6 +16,8 @@
package com.ning.billing.payment.provider;
+import java.math.BigDecimal;
+import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
@@ -33,6 +35,7 @@ import com.ning.billing.account.api.Account;
import com.ning.billing.invoice.api.Invoice;
import com.ning.billing.payment.api.CreditCardPaymentMethodInfo;
import com.ning.billing.payment.api.DefaultPaymentInfoEvent;
+import com.ning.billing.payment.api.Payment;
import com.ning.billing.payment.api.PaymentInfoEvent;
import com.ning.billing.payment.api.PaymentMethodInfo;
import com.ning.billing.payment.api.PaypalPaymentMethodInfo;
@@ -41,13 +44,14 @@ import com.ning.billing.payment.plugin.api.PaymentInfoPlugin;
import com.ning.billing.payment.plugin.api.PaymentPluginApiException;
import com.ning.billing.payment.plugin.api.PaymentProviderAccount;
import com.ning.billing.payment.plugin.api.PaymentProviderPlugin;
+import com.ning.billing.payment.plugin.api.PaymentInfoPlugin.PaymentPluginStatus;
import com.ning.billing.util.clock.Clock;
public class MockPaymentProviderPlugin implements PaymentProviderPlugin {
private final AtomicBoolean makeNextInvoiceFail = new AtomicBoolean(false);
private final AtomicBoolean makeAllInvoicesFail = new AtomicBoolean(false);
- private final Map<UUID, PaymentInfoEvent> payments = new ConcurrentHashMap<UUID, PaymentInfoEvent>();
+ private final Map<UUID, PaymentInfoPlugin> payments = new ConcurrentHashMap<UUID, PaymentInfoPlugin>();
private final Map<String, PaymentProviderAccount> accounts = new ConcurrentHashMap<String, PaymentProviderAccount>();
private final Map<String, PaymentMethodInfo> paymentMethods = new ConcurrentHashMap<String, PaymentMethodInfo>();
private final Clock clock;
@@ -57,7 +61,7 @@ public class MockPaymentProviderPlugin implements PaymentProviderPlugin {
this.clock = clock;
}
- public void makeNextInvoiceFail() {
+ public void makeNextPaymentFail() {
makeNextInvoiceFail.set(true);
}
@@ -66,49 +70,35 @@ public class MockPaymentProviderPlugin implements PaymentProviderPlugin {
}
@Override
- public PaymentInfoPlugin processInvoice(Account account, Invoice invoice) throws PaymentPluginApiException {
+ public PaymentInfoPlugin processPayment(String externalKey, UUID paymentId, BigDecimal amount) throws PaymentPluginApiException {
if (makeNextInvoiceFail.getAndSet(false) || makeAllInvoicesFail.get()) {
throw new PaymentPluginApiException("", "test error");
}
- // STEPH
-/*
- PaymentInfoEvent payment = new DefaultPaymentInfoEvent.Builder().setId(UUID.randomUUID())
- .setExternalPaymentId("238957t49regyuihfd")
- .setAmount(invoice.getBalance())
- .setStatus("Processed")
- .setBankIdentificationNumber("1234")
- .setCreatedDate(clock.getUTCNow())
- .setEffectiveDate(clock.getUTCNow())
- .setPaymentNumber("12345")
- .setReferenceId("12345")
- .setType("Electronic")
- .setPaymentMethodId("123-456-678-89")
- .build();
-
- return new MockPaymentInfoPlugin(payment);
- *
- */
- return null;
+
+ PaymentInfoPlugin result = new MockPaymentInfoPlugin(amount, clock.getUTCNow(), clock.getUTCNow(), PaymentPluginStatus.PROCESSED, null);
+ payments.put(paymentId, result);
+ return result;
}
@Override
- public PaymentInfoPlugin getPaymentInfo(String paymentId) throws PaymentPluginApiException {
- PaymentInfoEvent payment = payments.get(paymentId);
+ public PaymentInfoPlugin getPaymentInfo(UUID paymentId) throws PaymentPluginApiException {
+ PaymentInfoPlugin payment = payments.get(paymentId);
if (payment == null) {
throw new PaymentPluginApiException("", "No payment found for id " + paymentId);
}
- /* return new MockPaymentInfoPlugin(payment); */
- return null;
+ return payment;
}
@Override
public String createPaymentProviderAccount(Account account) throws PaymentPluginApiException {
if (account != null) {
String id = String.valueOf(RandomStringUtils.randomAlphanumeric(10));
+ String paymentMethodId = String.valueOf(RandomStringUtils.randomAlphanumeric(10));
accounts.put(account.getExternalKey(),
new PaymentProviderAccount.Builder().setAccountKey(account.getExternalKey())
.setId(id)
+ .setDefaultPaymentMethod(paymentMethodId)
.build());
return id;
}
diff --git a/payment/src/test/java/com/ning/billing/payment/TestRetryService.java b/payment/src/test/java/com/ning/billing/payment/TestRetryService.java
index e247d4d..7156c12 100644
--- a/payment/src/test/java/com/ning/billing/payment/TestRetryService.java
+++ b/payment/src/test/java/com/ning/billing/payment/TestRetryService.java
@@ -81,8 +81,6 @@ public class TestRetryService {
@Inject
private PaymentProviderPluginRegistry registry;
@Inject
- private PaymentDao paymentDao;
- @Inject
private FailedPaymentRetryService retryService;
@Inject
private NotificationQueueService notificationQueueService;
@@ -138,7 +136,7 @@ public class TestRetryService {
new BigDecimal("1.0"),
Currency.USD));
- mockPaymentProviderPlugin.makeNextInvoiceFail();
+ mockPaymentProviderPlugin.makeNextPaymentFail();
boolean failed = false;
try {
paymentApi.createPayment(account.getExternalKey(), invoice.getId(), context);