killbill-uncached

See #329 Add missing createCaptureWithPaymentControl

6/10/2015 7:27:58 PM

Details

diff --git a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestPaymentWithControl.java b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestPaymentWithControl.java
new file mode 100644
index 0000000..9ab369b
--- /dev/null
+++ b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestPaymentWithControl.java
@@ -0,0 +1,205 @@
+/*
+ * Copyright 2014-2015 Groupon, Inc
+ * Copyright 2014-2015 The Billing Project, LLC
+ *
+ * The Billing Project 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 org.killbill.billing.beatrix.integration;
+
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+
+import javax.inject.Inject;
+
+import org.killbill.billing.account.api.Account;
+import org.killbill.billing.account.api.AccountData;
+import org.killbill.billing.api.TestApiListener.NextEvent;
+import org.killbill.billing.catalog.api.Currency;
+import org.killbill.billing.osgi.api.OSGIServiceDescriptor;
+import org.killbill.billing.osgi.api.OSGIServiceRegistration;
+import org.killbill.billing.payment.api.Payment;
+import org.killbill.billing.payment.api.PaymentOptions;
+import org.killbill.billing.payment.api.PluginProperty;
+import org.killbill.billing.payment.api.TransactionType;
+import org.killbill.billing.routing.plugin.api.OnFailurePaymentRoutingResult;
+import org.killbill.billing.routing.plugin.api.OnSuccessPaymentRoutingResult;
+import org.killbill.billing.routing.plugin.api.PaymentRoutingApiException;
+import org.killbill.billing.routing.plugin.api.PaymentRoutingContext;
+import org.killbill.billing.routing.plugin.api.PaymentRoutingPluginApi;
+import org.killbill.billing.routing.plugin.api.PriorPaymentRoutingResult;
+import org.testng.Assert;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import com.google.common.base.Predicate;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
+
+public class TestPaymentWithControl extends TestIntegrationBase {
+
+    private final static String TEST_PAYMENT_WITH_CONTROL = "TestPaymentWithControl";
+
+    private TestPaymentRoutingPluginApi testPaymentRoutingWithControl;
+    private List<PluginProperty> properties;
+    private PaymentOptions paymentOptions;
+
+    @Inject
+    private OSGIServiceRegistration<PaymentRoutingPluginApi> pluginRegistry;
+
+    @BeforeClass(groups = "slow")
+    public void beforeClass() throws Exception {
+        super.beforeClass();
+
+        this.testPaymentRoutingWithControl = new TestPaymentRoutingPluginApi();
+        pluginRegistry.registerService(new OSGIServiceDescriptor() {
+            @Override
+            public String getPluginSymbolicName() {
+                return TEST_PAYMENT_WITH_CONTROL;
+            }
+
+            @Override
+            public String getRegistrationName() {
+                return TEST_PAYMENT_WITH_CONTROL;
+            }
+        }, testPaymentRoutingWithControl);
+
+        properties = new ArrayList<PluginProperty>();
+        paymentOptions = new PaymentOptions() {
+            @Override
+            public boolean isExternalPayment() {
+                return false;
+            }
+
+            @Override
+            public List<String> getPaymentControlPluginNames() {
+                return ImmutableList.of(TEST_PAYMENT_WITH_CONTROL);
+            }
+        };
+
+        properties.add(new PluginProperty("name", TEST_PAYMENT_WITH_CONTROL, false));
+
+    }
+
+    @BeforeMethod(groups = "slow")
+    public void beforeMethod() throws Exception {
+        super.beforeMethod();
+        testPaymentRoutingWithControl.reset();
+    }
+
+    @Test(groups = "slow")
+    public void testAuthCaptureWithPaymentControl() throws Exception {
+
+        final AccountData accountData = getAccountData(1);
+        final Account account = createAccountWithNonOsgiPaymentMethod(accountData);
+
+        busHandler.pushExpectedEvents(NextEvent.PAYMENT);
+        final Payment payment = paymentApi.createAuthorizationWithPaymentControl(account, account.getPaymentMethodId(), null, BigDecimal.ONE, account.getCurrency(), null, null,
+                                                                                 properties, paymentOptions, callContext);
+        assertListenerStatus();
+
+        busHandler.pushExpectedEvents(NextEvent.PAYMENT);
+        paymentApi.createCaptureWithPaymentControl(account, payment.getId(), BigDecimal.ONE, account.getCurrency(), null, properties, paymentOptions, callContext);
+        assertListenerStatus();
+
+        Assert.assertEquals(testPaymentRoutingWithControl.getCalls().size(), 2);
+        Assert.assertEquals(testPaymentRoutingWithControl.getCalls().get(TransactionType.AUTHORIZE.toString()), new Integer(1));
+        Assert.assertEquals(testPaymentRoutingWithControl.getCalls().get(TransactionType.CAPTURE.toString()), new Integer(1));
+    }
+
+    @Test(groups = "slow")
+    public void testAuthVoidWithPaymentControl() throws Exception {
+        final AccountData accountData = getAccountData(1);
+        final Account account = createAccountWithNonOsgiPaymentMethod(accountData);
+
+        busHandler.pushExpectedEvents(NextEvent.PAYMENT);
+        final Payment payment = paymentApi.createAuthorizationWithPaymentControl(account, account.getPaymentMethodId(), null, BigDecimal.ONE, account.getCurrency(), null, null,
+                                                                                 properties, paymentOptions, callContext);
+        assertListenerStatus();
+
+        busHandler.pushExpectedEvents(NextEvent.PAYMENT);
+        paymentApi.createVoidWithPaymentControl(account, payment.getId(), null, properties, paymentOptions, callContext);
+        assertListenerStatus();
+        Assert.assertEquals(testPaymentRoutingWithControl.getCalls().size(), 2);
+        Assert.assertEquals(testPaymentRoutingWithControl.getCalls().get(TransactionType.AUTHORIZE.toString()), new Integer(1));
+        Assert.assertEquals(testPaymentRoutingWithControl.getCalls().get(TransactionType.VOID.toString()), new Integer(1));
+    }
+
+    public class TestPaymentRoutingPluginApi implements PaymentRoutingPluginApi {
+
+        private final Map<String, Integer> calls;
+
+        public TestPaymentRoutingPluginApi() {
+            calls = new HashMap<String, Integer>();
+        }
+
+        public Map<String, Integer> getCalls() {
+            return calls;
+        }
+
+        public void reset() {
+            calls.clear();
+        }
+
+        @Override
+        public PriorPaymentRoutingResult priorCall(final PaymentRoutingContext paymentRoutingContext, final Iterable<PluginProperty> properties) throws PaymentRoutingApiException {
+            return new PriorPaymentRoutingResult() {
+                @Override
+                public boolean isAborted() {
+                    return false;
+                }
+                @Override
+                public BigDecimal getAdjustedAmount() {
+                    return null;
+                }
+                @Override
+                public Currency getAdjustedCurrency() {
+                    return null;
+                }
+                @Override
+                public UUID getAdjustedPaymentMethodId() {
+                    return null;
+                }
+                @Override
+                public Iterable<PluginProperty> getAdjustedPluginProperties() {
+                    return null;
+                }
+            };
+        }
+
+        @Override
+        public OnSuccessPaymentRoutingResult onSuccessCall(final PaymentRoutingContext paymentRoutingContext, final Iterable<PluginProperty> properties) throws PaymentRoutingApiException {
+            final PluginProperty nameProperty = Iterables.tryFind(properties, new Predicate<PluginProperty>() {
+                @Override
+                public boolean apply(final PluginProperty input) {
+                    return input.getKey().equals("name");
+                }
+            }).orNull();
+            if (nameProperty != null && nameProperty.getValue().equals(TEST_PAYMENT_WITH_CONTROL)) {
+                final Integer result = calls.get(paymentRoutingContext.getTransactionType());
+                calls.put(paymentRoutingContext.getTransactionType().toString(), result == null ? new Integer(1) : new Integer(result.intValue() + 1));
+            }
+            return new OnSuccessPaymentRoutingResult() {};
+        }
+
+        @Override
+        public OnFailurePaymentRoutingResult onFailureCall(final PaymentRoutingContext paymentRoutingContext, final Iterable<PluginProperty> properties) throws PaymentRoutingApiException {
+            return null;
+        }
+    }
+}
diff --git a/payment/src/main/java/org/killbill/billing/payment/api/DefaultPaymentApi.java b/payment/src/main/java/org/killbill/billing/payment/api/DefaultPaymentApi.java
index eeb73f3..23fe159 100644
--- a/payment/src/main/java/org/killbill/billing/payment/api/DefaultPaymentApi.java
+++ b/payment/src/main/java/org/killbill/billing/payment/api/DefaultPaymentApi.java
@@ -85,7 +85,7 @@ public class DefaultPaymentApi implements PaymentApi {
     }
 
     @Override
-    public Payment createAuthorizationWithPaymentControl(final Account account, final UUID paymentMethodId, final UUID paymentId, final BigDecimal amount, final Currency currency,
+    public Payment createAuthorizationWithPaymentControl(final Account account, final UUID paymentMethodId, @Nullable final UUID paymentId, final BigDecimal amount, final Currency currency,
                                                          @Nullable final String paymentExternalKey, @Nullable final String paymentTransactionExternalKey,
                                                          final Iterable<PluginProperty> properties, final PaymentOptions paymentOptions, final CallContext callContext) throws PaymentApiException {
         final List<String> paymentControlPluginNames = toPaymentControlPluginNames(paymentOptions);
@@ -125,6 +125,25 @@ public class DefaultPaymentApi implements PaymentApi {
     }
 
     @Override
+    public Payment createCaptureWithPaymentControl(final Account account, final UUID paymentId, final BigDecimal amount, final Currency currency, @Nullable final String paymentTransactionExternalKey,
+                                                   final Iterable<PluginProperty> properties, final PaymentOptions paymentOptions, final CallContext callContext) throws PaymentApiException {
+        final List<String> paymentControlPluginNames = toPaymentControlPluginNames(paymentOptions);
+        if (paymentControlPluginNames.isEmpty()) {
+            return createCapture(account, paymentId, amount, currency, paymentTransactionExternalKey, properties, callContext);
+        }
+
+        checkNotNullParameter(account, "account");
+        checkNotNullParameter(paymentId, "paymentId");
+        checkNotNullParameter(currency, "currency");
+        checkNotNullParameter(properties, "plugin properties");
+        checkPositiveAmount(amount);
+
+        final InternalCallContext internalCallContext = internalCallContextFactory.createInternalCallContext(account.getId(), callContext);
+        return pluginRoutingPaymentProcessor.createCapture(IS_API_PAYMENT, account, paymentId, amount, currency, paymentTransactionExternalKey,
+                                              properties, paymentControlPluginNames, callContext, internalCallContext);
+    }
+
+    @Override
     public Payment createPurchase(final Account account, final UUID paymentMethodId, @Nullable final UUID paymentId, final BigDecimal amount, final Currency currency, @Nullable final String paymentExternalKey, @Nullable final String paymentTransactionExternalKey,
                                   final Iterable<PluginProperty> properties, final CallContext callContext) throws PaymentApiException {
         checkNotNullParameter(account, "account");
@@ -190,6 +209,24 @@ public class DefaultPaymentApi implements PaymentApi {
     }
 
     @Override
+    public Payment createVoidWithPaymentControl(final Account account, final UUID paymentId, final String paymentTransactionExternalKey, final Iterable<PluginProperty> properties, final PaymentOptions paymentOptions, final CallContext callContext) throws PaymentApiException {
+        final List<String> paymentControlPluginNames = toPaymentControlPluginNames(paymentOptions);
+        if (paymentControlPluginNames.isEmpty()) {
+            return createVoid(account, paymentId, paymentTransactionExternalKey, properties, callContext);
+        }
+
+        checkNotNullParameter(account, "account");
+        checkNotNullParameter(paymentId, "paymentId");
+        checkNotNullParameter(properties, "plugin properties");
+
+        logAPICall(TransactionType.VOID.name(), account, null, paymentId, null, null, null, null, paymentTransactionExternalKey);
+
+        final InternalCallContext internalCallContext = internalCallContextFactory.createInternalCallContext(account.getId(), callContext);
+        return pluginRoutingPaymentProcessor.createVoid(IS_API_PAYMENT, account, paymentId, paymentTransactionExternalKey,
+                                           properties, paymentControlPluginNames, callContext, internalCallContext);
+    }
+
+    @Override
     public Payment createRefund(final Account account, final UUID paymentId, final BigDecimal amount, final Currency currency, @Nullable final String paymentTransactionExternalKey, final Iterable<PluginProperty> properties,
                                 final CallContext callContext) throws PaymentApiException {
 
@@ -286,7 +323,7 @@ public class DefaultPaymentApi implements PaymentApi {
     }
 
     @Override
-    public Payment notifyPendingTransactionOfStateChangedWithPaymentControl(final Account account, final UUID paymentTransactionId, final boolean isSuccess, final PaymentOptions paymentOptions, final CallContext context) throws PaymentApiException {
+    public Payment notifyPendingTransactionOfStateChangedWithPaymentControl(final Account account, final UUID paymentTransactionId, final boolean isSuccess, final PaymentOptions paymentOptions, final CallContext callContext) throws PaymentApiException {
         throw new IllegalStateException("Not implemented");
     }
 
@@ -320,7 +357,7 @@ public class DefaultPaymentApi implements PaymentApi {
         checkPositiveAmount(amount);
 
         final InternalCallContext internalCallContext = internalCallContextFactory.createInternalCallContext(account.getId(), callContext);
-        return pluginRoutingPaymentProcessor.createChargeback(account, paymentId, paymentTransactionExternalKey, amount, currency,
+        return pluginRoutingPaymentProcessor.createChargeback(IS_API_PAYMENT, account, paymentId, paymentTransactionExternalKey, amount, currency,
                                                               paymentControlPluginNames, callContext, internalCallContext);
     }
 
diff --git a/payment/src/main/java/org/killbill/billing/payment/api/DefaultPaymentGatewayApi.java b/payment/src/main/java/org/killbill/billing/payment/api/DefaultPaymentGatewayApi.java
index 526b9db..c9adbaf 100644
--- a/payment/src/main/java/org/killbill/billing/payment/api/DefaultPaymentGatewayApi.java
+++ b/payment/src/main/java/org/killbill/billing/payment/api/DefaultPaymentGatewayApi.java
@@ -53,7 +53,17 @@ public class DefaultPaymentGatewayApi implements PaymentGatewayApi {
     }
 
     @Override
+    public HostedPaymentPageFormDescriptor buildFormDescriptorWithPaymentControl(final Account account, final UUID uuid, final Iterable<PluginProperty> iterable, final Iterable<PluginProperty> iterable1, final PaymentOptions paymentOptions, final CallContext callContext) throws PaymentApiException {
+        throw new IllegalStateException("Not implemented");
+    }
+
+    @Override
     public GatewayNotification processNotification(final String notification, final String pluginName, final Iterable<PluginProperty> properties, final CallContext callContext) throws PaymentApiException {
         return paymentGatewayProcessor.processNotification(notification, pluginName, properties, callContext);
     }
+
+    @Override
+    public GatewayNotification processNotificationWithPaymentControl(final String s, final String s1, final Iterable<PluginProperty> iterable, final PaymentOptions paymentOptions, final CallContext callContext) throws PaymentApiException {
+        throw new IllegalStateException("Not implemented");
+    }
 }
diff --git a/payment/src/main/java/org/killbill/billing/payment/core/PluginRoutingPaymentProcessor.java b/payment/src/main/java/org/killbill/billing/payment/core/PluginRoutingPaymentProcessor.java
index a6ca074..f676ffa 100644
--- a/payment/src/main/java/org/killbill/billing/payment/core/PluginRoutingPaymentProcessor.java
+++ b/payment/src/main/java/org/killbill/billing/payment/core/PluginRoutingPaymentProcessor.java
@@ -135,7 +135,7 @@ public class PluginRoutingPaymentProcessor extends ProcessorBase {
     }
 
     public Payment createVoid(final boolean isApiPayment, final Account account, final UUID paymentId, final String transactionExternalKey,
-                              final Iterable<PluginProperty> properties, final CallContext callContext, final InternalCallContext internalCallContext) throws PaymentApiException {
+                              final Iterable<PluginProperty> properties, final List<String> paymentControlPluginNames, final CallContext callContext, final InternalCallContext internalCallContext) throws PaymentApiException {
         return pluginControlledPaymentAutomatonRunner.run(isApiPayment,
                                                           TransactionType.VOID,
                                                           account,
@@ -146,7 +146,7 @@ public class PluginRoutingPaymentProcessor extends ProcessorBase {
                                                           null,
                                                           null,
                                                           properties,
-                                                          null,
+                                                          paymentControlPluginNames,
                                                           callContext, internalCallContext);
     }
 
@@ -183,9 +183,9 @@ public class PluginRoutingPaymentProcessor extends ProcessorBase {
                                                           callContext, internalCallContext);
     }
 
-    public Payment createChargeback(final Account account, final UUID paymentId, final String transactionExternalKey, final BigDecimal amount, final Currency currency,
+    public Payment createChargeback(final boolean isApiPayment, final Account account, final UUID paymentId, final String transactionExternalKey, final BigDecimal amount, final Currency currency,
                                     final List<String> paymentControlPluginNames, final CallContext callContext, final InternalCallContext internalCallContext) throws PaymentApiException {
-        return pluginControlledPaymentAutomatonRunner.run(true,
+        return pluginControlledPaymentAutomatonRunner.run(isApiPayment,
                                                           TransactionType.CHARGEBACK,
                                                           account,
                                                           null,
diff --git a/payment/src/main/java/org/killbill/billing/payment/core/sm/PluginRoutingPaymentAutomatonRunner.java b/payment/src/main/java/org/killbill/billing/payment/core/sm/PluginRoutingPaymentAutomatonRunner.java
index 1731335..27d20b0 100644
--- a/payment/src/main/java/org/killbill/billing/payment/core/sm/PluginRoutingPaymentAutomatonRunner.java
+++ b/payment/src/main/java/org/killbill/billing/payment/core/sm/PluginRoutingPaymentAutomatonRunner.java
@@ -179,4 +179,5 @@ public class PluginRoutingPaymentAutomatonRunner extends PaymentAutomatonRunner 
         }
         return callback;
     }
+
 }
diff --git a/payment/src/main/java/org/killbill/billing/payment/core/sm/RetryCaptureOperationCallback.java b/payment/src/main/java/org/killbill/billing/payment/core/sm/RetryCaptureOperationCallback.java
index e9d3a28..8bbf9ef 100644
--- a/payment/src/main/java/org/killbill/billing/payment/core/sm/RetryCaptureOperationCallback.java
+++ b/payment/src/main/java/org/killbill/billing/payment/core/sm/RetryCaptureOperationCallback.java
@@ -36,7 +36,7 @@ public class RetryCaptureOperationCallback extends RetryOperationCallback {
         return paymentProcessor.createCapture(retryablePaymentStateContext.isApiPayment(),
                                               retryablePaymentStateContext.getAttemptId(),
                                               retryablePaymentStateContext.getAccount(),
-                                              retryablePaymentStateContext.getPaymentMethodId(),
+                                              retryablePaymentStateContext.getPaymentId(),
                                               retryablePaymentStateContext.getAmount(),
                                               retryablePaymentStateContext.getCurrency(),
                                               retryablePaymentStateContext.getPaymentTransactionExternalKey(),