killbill-uncached

Merge pull request #575 from andrenpaes/fix-state-change-notification-api Add

7/13/2016 8:45:30 PM

Details

diff --git a/payment/src/main/java/org/killbill/billing/payment/core/PaymentProcessor.java b/payment/src/main/java/org/killbill/billing/payment/core/PaymentProcessor.java
index 43eb3bf..decfbd4 100644
--- a/payment/src/main/java/org/killbill/billing/payment/core/PaymentProcessor.java
+++ b/payment/src/main/java/org/killbill/billing/payment/core/PaymentProcessor.java
@@ -162,7 +162,8 @@ public class PaymentProcessor extends ProcessorBase {
 
         final OperationResult overridePluginResult = isSuccess ? OperationResult.SUCCESS : OperationResult.FAILURE;
 
-        return performOperation(true, null, transactionModelDao.getTransactionType(), account, null, transactionModelDao.getPaymentId(),
+        final boolean runJanitor = false;
+        return performOperation(true, runJanitor, null, transactionModelDao.getTransactionType(), account, null, transactionModelDao.getPaymentId(),
                                 transactionModelDao.getId(), transactionModelDao.getAmount(), transactionModelDao.getCurrency(), null, transactionModelDao.getTransactionExternalKey(), true,
                                 overridePluginResult, PLUGIN_PROPERTIES, callContext, internalCallContext);
     }
@@ -347,6 +348,29 @@ public class PaymentProcessor extends ProcessorBase {
                                      final Iterable<PluginProperty> properties,
                                      final CallContext callContext,
                                      final InternalCallContext internalCallContext) throws PaymentApiException {
+        boolean runJanitor = true;
+        return performOperation(isApiPayment, runJanitor, attemptId, transactionType, account, paymentMethodId, paymentId,
+                                transactionId, amount, currency, paymentExternalKey, paymentTransactionExternalKey,
+                                shouldLockAccountAndDispatch, overridePluginOperationResult, properties, callContext, internalCallContext);
+    }
+
+    private Payment performOperation(final boolean isApiPayment,
+                                     final boolean runJanitor,
+                                     @Nullable final UUID attemptId,
+                                     final TransactionType transactionType,
+                                     final Account account,
+                                     @Nullable final UUID paymentMethodId,
+                                     @Nullable final UUID paymentId,
+                                     @Nullable final UUID transactionId,
+                                     @Nullable final BigDecimal amount,
+                                     @Nullable final Currency currency,
+                                     @Nullable final String paymentExternalKey,
+                                     @Nullable final String paymentTransactionExternalKey,
+                                     final boolean shouldLockAccountAndDispatch,
+                                     @Nullable final OperationResult overridePluginOperationResult,
+                                     final Iterable<PluginProperty> properties,
+                                     final CallContext callContext,
+                                     final InternalCallContext internalCallContext) throws PaymentApiException {
         final PaymentStateContext paymentStateContext = paymentAutomatonRunner.buildPaymentStateContext(isApiPayment,
                                                                                                         transactionType,
                                                                                                         account,
@@ -382,9 +406,11 @@ public class PaymentProcessor extends ProcessorBase {
                 if (transactionToComplete != null) {
                     // For completion calls, always invoke the Janitor first to get the latest state. The state machine will then
                     // prevent disallowed transitions in case the state couldn't be fixed (or if it's already in a final state).
-                    final PaymentPluginApi plugin = getPaymentProviderPlugin(paymentModelDao.getPaymentMethodId(), internalCallContext);
-                    final List<PaymentTransactionInfoPlugin> pluginTransactions = getPaymentTransactionInfoPlugins(plugin, paymentModelDao, properties, callContext);
-                    paymentModelDao = invokeJanitor(paymentModelDao, paymentTransactionsForCurrentPayment, pluginTransactions, internalCallContext);
+                    if (runJanitor) {
+                        final PaymentPluginApi plugin = getPaymentProviderPlugin(paymentModelDao.getPaymentMethodId(), internalCallContext);
+                        final List<PaymentTransactionInfoPlugin> pluginTransactions = getPaymentTransactionInfoPlugins(plugin, paymentModelDao, properties, callContext);
+                        paymentModelDao = invokeJanitor(paymentModelDao, paymentTransactionsForCurrentPayment, pluginTransactions, internalCallContext);
+                    }
 
                     final UUID transactionToCompleteId = transactionToComplete.getId();
                     transactionToComplete = Iterables.<PaymentTransactionModelDao>find(paymentTransactionsForCurrentPayment,
diff --git a/payment/src/test/java/org/killbill/billing/payment/core/TestPaymentProcessor.java b/payment/src/test/java/org/killbill/billing/payment/core/TestPaymentProcessor.java
index fe0fe2a..25aee73 100644
--- a/payment/src/test/java/org/killbill/billing/payment/core/TestPaymentProcessor.java
+++ b/payment/src/test/java/org/killbill/billing/payment/core/TestPaymentProcessor.java
@@ -199,6 +199,29 @@ public class TestPaymentProcessor extends PaymentTestSuiteWithEmbeddedDB {
         paymentBusListener.verify(1, account.getId(), paymentId, TEN, TransactionStatus.SUCCESS);
     }
 
+    @Test(groups = "slow")
+    public void testNotifyPendingPaymentOfStateChanged() throws Exception {
+        final String paymentExternalKey = UUID.randomUUID().toString();
+        final Iterable<PluginProperty> pluginPropertiesToDriveTransationToPending = ImmutableList.<PluginProperty>of(new PluginProperty(MockPaymentProviderPlugin.PLUGIN_PROPERTY_PAYMENT_PLUGIN_STATUS_OVERRIDE, PaymentPluginStatus.PENDING, false));
+
+        // Create Pending AUTH
+        final String authorizationKey = UUID.randomUUID().toString();
+        final Payment authorization = paymentProcessor.createAuthorization(true, null, account, null, null, TEN, CURRENCY, paymentExternalKey, authorizationKey,
+                                                                           SHOULD_LOCK_ACCOUNT, pluginPropertiesToDriveTransationToPending, callContext, internalCallContext);
+        final PaymentTransaction pendingTransaction = authorization.getTransactions().get(0);
+        Assert.assertEquals(pendingTransaction.getTransactionStatus(), TransactionStatus.PENDING);
+
+        final UUID transactionId = pendingTransaction.getId();
+        // Override plugin status of payment
+        mockPaymentProviderPlugin.overridePaymentPluginStatus(authorization.getId(), transactionId, PaymentPluginStatus.PROCESSED);
+        // Notify that state has changed, after changing the state in the plugin
+        final Payment updatedPayment = paymentProcessor.notifyPendingPaymentOfStateChanged(account, transactionId, true, callContext, internalCallContext);
+        verifyPayment(updatedPayment, paymentExternalKey, TEN, ZERO, ZERO, 1);
+
+        final PaymentTransaction updatedTransaction = updatedPayment.getTransactions().get(0);
+        Assert.assertEquals(updatedTransaction.getTransactionStatus(), TransactionStatus.SUCCESS);
+    }
+
     private void verifyPayment(final Payment payment, final String paymentExternalKey,
                                final BigDecimal authAmount, final BigDecimal capturedAmount, final BigDecimal refundedAmount,
                                final int transactionsSize) {