killbill-memoizeit

payment: fix for control plugins * DefaultPaymentGatewayApi

11/30/2015 9:46:03 PM

Details

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 39117a5..6ac3cb8 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
@@ -70,8 +70,8 @@ public class DefaultPaymentGatewayApi extends DefaultApiBase implements PaymentG
 
         return executeWithPaymentControl(account, paymentMethodId, properties, paymentOptions, callContext, new WithPaymentControlCallback<HostedPaymentPageFormDescriptor>() {
             @Override
-            public HostedPaymentPageFormDescriptor doPaymentGatewayApiOperation(final Iterable<PluginProperty> adjustedPluginProperties) throws PaymentApiException {
-                return buildFormDescriptor(account, paymentMethodId, customFields, adjustedPluginProperties, callContext);
+            public HostedPaymentPageFormDescriptor doPaymentGatewayApiOperation(final UUID adjustedPaymentMethodId, final Iterable<PluginProperty> adjustedPluginProperties) throws PaymentApiException {
+                return buildFormDescriptor(account, adjustedPaymentMethodId, customFields, adjustedPluginProperties, callContext);
             }
         });
     }
@@ -85,15 +85,19 @@ public class DefaultPaymentGatewayApi extends DefaultApiBase implements PaymentG
     public GatewayNotification processNotificationWithPaymentControl(final String notification, final String pluginName, final Iterable<PluginProperty> properties, final PaymentOptions paymentOptions, final CallContext callContext) throws PaymentApiException {
         return executeWithPaymentControl(null, null, properties, paymentOptions, callContext, new WithPaymentControlCallback<GatewayNotification>() {
             @Override
-            public GatewayNotification doPaymentGatewayApiOperation(final Iterable<PluginProperty> adjustedPluginProperties) throws PaymentApiException {
-                return processNotification(notification, pluginName, adjustedPluginProperties, callContext);
+            public GatewayNotification doPaymentGatewayApiOperation(final UUID adjustedPaymentMethodId, final Iterable<PluginProperty> adjustedPluginProperties) throws PaymentApiException {
+                if (adjustedPaymentMethodId == null) {
+                    return paymentGatewayProcessor.processNotification(notification, pluginName, properties, callContext);
+                } else {
+                    return paymentGatewayProcessor.processNotification(notification, adjustedPaymentMethodId, properties, callContext);
+                }
             }
         });
     }
 
-
     private interface WithPaymentControlCallback<T> {
-        T doPaymentGatewayApiOperation(final Iterable<PluginProperty> adjustedPluginProperties) throws PaymentApiException;
+
+        T doPaymentGatewayApiOperation(final UUID adjustedPaymentMethodId, final Iterable<PluginProperty> adjustedPluginProperties) throws PaymentApiException;
     }
 
     private <T> T executeWithPaymentControl(@Nullable final Account account,
@@ -105,7 +109,7 @@ public class DefaultPaymentGatewayApi extends DefaultApiBase implements PaymentG
 
         final List<String> paymentControlPluginNames = toPaymentControlPluginNames(paymentOptions);
         if (paymentControlPluginNames.isEmpty()) {
-            return callback.doPaymentGatewayApiOperation(properties);
+            return callback.doPaymentGatewayApiOperation(paymentMethodId, properties);
         }
 
         final PriorPaymentControlResult priorCallResult;
@@ -121,7 +125,7 @@ public class DefaultPaymentGatewayApi extends DefaultApiBase implements PaymentG
         }
 
         try {
-            final T result = callback.doPaymentGatewayApiOperation(priorCallResult.getAdjustedPluginProperties());
+            final T result = callback.doPaymentGatewayApiOperation(priorCallResult.getAdjustedPaymentMethodId(), priorCallResult.getAdjustedPluginProperties());
             controlPluginRunner.executePluginOnSuccessCalls(account,
                                                             paymentMethodId,
                                                             null, null, null, null, null,
diff --git a/payment/src/main/java/org/killbill/billing/payment/core/PaymentGatewayProcessor.java b/payment/src/main/java/org/killbill/billing/payment/core/PaymentGatewayProcessor.java
index 896a7c9..eaf2e5f 100644
--- a/payment/src/main/java/org/killbill/billing/payment/core/PaymentGatewayProcessor.java
+++ b/payment/src/main/java/org/killbill/billing/payment/core/PaymentGatewayProcessor.java
@@ -24,6 +24,7 @@ import java.util.concurrent.TimeUnit;
 import javax.inject.Inject;
 
 import org.killbill.billing.ErrorCode;
+import org.killbill.billing.ObjectType;
 import org.killbill.billing.account.api.Account;
 import org.killbill.billing.account.api.AccountInternalApi;
 import org.killbill.billing.callcontext.InternalCallContext;
@@ -76,6 +77,11 @@ public class PaymentGatewayProcessor extends ProcessorBase {
         this.paymentPluginNotificationDispatcher = new PluginDispatcher<GatewayNotification>(paymentPluginTimeoutSec, executors);
     }
 
+    public GatewayNotification processNotification(final String notification, final UUID paymentMethodId, final Iterable<PluginProperty> properties, final CallContext callContext) throws PaymentApiException {
+        final String pluginName = getPaymentProviderPluginName(paymentMethodId, internalCallContextFactory.createInternalCallContext(paymentMethodId, ObjectType.PAYMENT_METHOD, callContext));
+        return processNotification(notification, pluginName, properties, callContext);
+    }
+
     public GatewayNotification processNotification(final String notification, final String pluginName, final Iterable<PluginProperty> properties, final CallContext callContext) throws PaymentApiException {
         return dispatchWithExceptionHandling(null,
                                              pluginName,
diff --git a/payment/src/main/java/org/killbill/billing/payment/core/sm/control/ControlPluginRunner.java b/payment/src/main/java/org/killbill/billing/payment/core/sm/control/ControlPluginRunner.java
index 2624d3e..7d4e20b 100644
--- a/payment/src/main/java/org/killbill/billing/payment/core/sm/control/ControlPluginRunner.java
+++ b/payment/src/main/java/org/killbill/billing/payment/core/sm/control/ControlPluginRunner.java
@@ -76,6 +76,9 @@ public class ControlPluginRunner {
         PriorPaymentControlResult prevResult = new DefaultPriorPaymentControlResult(false, amount, currency, paymentMethodId, pluginProperties);
 
         // Those values are adjusted prior each call with the result of what previous call to plugin returned
+        UUID inputPaymentMethodId = paymentMethodId;
+        BigDecimal inputAmount = amount;
+        Currency inputCurrency = currency;
         Iterable<PluginProperty> inputPluginProperties = pluginProperties;
         PaymentControlContext inputPaymentControlContext = new DefaultPaymentControlContext(account,
                                                                                             paymentMethodId,
@@ -101,6 +104,15 @@ public class ControlPluginRunner {
             log.debug("Calling priorCall of plugin {}", pluginName);
             prevResult = plugin.priorCall(inputPaymentControlContext, inputPluginProperties);
             log.debug("Successful executed priorCall of plugin {}", pluginName);
+            if (prevResult.getAdjustedPaymentMethodId() != null) {
+                inputPaymentMethodId = prevResult.getAdjustedPaymentMethodId();
+            }
+            if (prevResult.getAdjustedAmount() != null) {
+                inputAmount = prevResult.getAdjustedAmount();
+            }
+            if (prevResult.getAdjustedCurrency() != null) {
+                inputCurrency = prevResult.getAdjustedCurrency();
+            }
             if (prevResult.getAdjustedPluginProperties() != null) {
                 inputPluginProperties = prevResult.getAdjustedPluginProperties();
             }
@@ -108,7 +120,7 @@ public class ControlPluginRunner {
                 break;
             }
             inputPaymentControlContext = new DefaultPaymentControlContext(account,
-                                                                          prevResult.getAdjustedPaymentMethodId() != null ? prevResult.getAdjustedPaymentMethodId() : paymentMethodId,
+                                                                          inputPaymentMethodId,
                                                                           paymentAttemptId,
                                                                           paymentId,
                                                                           paymentExternalKey,
@@ -116,13 +128,13 @@ public class ControlPluginRunner {
                                                                           paymentApiType,
                                                                           transactionType,
                                                                           hppType,
-                                                                          prevResult.getAdjustedAmount() != null ? prevResult.getAdjustedAmount() : amount,
-                                                                          prevResult.getAdjustedCurrency() != null ? prevResult.getAdjustedCurrency() : currency,
+                                                                          inputAmount,
+                                                                          inputCurrency,
                                                                           isApiPayment,
                                                                           callContext);
         }
         // Rebuild latest result to include inputPluginProperties
-        prevResult = new DefaultPriorPaymentControlResult(prevResult, inputPluginProperties);
+        prevResult = new DefaultPriorPaymentControlResult(prevResult.isAborted(), inputPaymentMethodId, inputAmount, inputCurrency, inputPluginProperties);
         return prevResult;
     }
 
diff --git a/payment/src/main/java/org/killbill/billing/payment/retry/DefaultPriorPaymentControlResult.java b/payment/src/main/java/org/killbill/billing/payment/retry/DefaultPriorPaymentControlResult.java
index df030b0..27ce65b 100644
--- a/payment/src/main/java/org/killbill/billing/payment/retry/DefaultPriorPaymentControlResult.java
+++ b/payment/src/main/java/org/killbill/billing/payment/retry/DefaultPriorPaymentControlResult.java
@@ -53,8 +53,8 @@ public class DefaultPriorPaymentControlResult implements PriorPaymentControlResu
     }
 
 
-    public DefaultPriorPaymentControlResult(final PriorPaymentControlResult input, final Iterable<PluginProperty> adjustedPluginProperties) {
-        this(input.isAborted(), input.getAdjustedAmount(), input.getAdjustedCurrency(), input.getAdjustedPaymentMethodId(), adjustedPluginProperties);
+    public DefaultPriorPaymentControlResult(final boolean isAborted, final UUID adjustedPaymentMethodId, final BigDecimal adjustedAmount, final Currency adjustedCurrency, final Iterable<PluginProperty> adjustedPluginProperties) {
+        this(isAborted, adjustedAmount, adjustedCurrency, adjustedPaymentMethodId, adjustedPluginProperties);
     }
 
     @Override
diff --git a/payment/src/test/java/org/killbill/billing/payment/api/TestPaymentGatewayApiWithPaymentControl.java b/payment/src/test/java/org/killbill/billing/payment/api/TestPaymentGatewayApiWithPaymentControl.java
index 356e566..680221b 100644
--- a/payment/src/test/java/org/killbill/billing/payment/api/TestPaymentGatewayApiWithPaymentControl.java
+++ b/payment/src/test/java/org/killbill/billing/payment/api/TestPaymentGatewayApiWithPaymentControl.java
@@ -147,7 +147,8 @@ public class TestPaymentGatewayApiWithPaymentControl extends PaymentTestSuiteNoD
 
         validationPlugin.setExpectedProperties(expectedProperties);
 
-        paymentGatewayApi.buildFormDescriptorWithPaymentControl(account, account.getPaymentMethodId(), ImmutableList.<PluginProperty>of(), initialProperties, paymentOptions, callContext);
+        // Set a random UUID to verify the plugin will successfully override it
+        paymentGatewayApi.buildFormDescriptorWithPaymentControl(account, UUID.randomUUID(), ImmutableList.<PluginProperty>of(), initialProperties, paymentOptions, callContext);
 
     }
 
@@ -205,7 +206,7 @@ public class TestPaymentGatewayApiWithPaymentControl extends PaymentTestSuiteNoD
 
     }
 
-    public static class TestPaymentGatewayApiControlPlugin implements PaymentControlPluginApi {
+    public class TestPaymentGatewayApiControlPlugin implements PaymentControlPluginApi {
 
         public static final String PLUGIN_NAME = "TestPaymentGatewayApiControlPlugin";
 
@@ -234,7 +235,7 @@ public class TestPaymentGatewayApiWithPaymentControl extends PaymentTestSuiteNoD
 
         @Override
         public PriorPaymentControlResult priorCall(final PaymentControlContext paymentControlContext, final Iterable<PluginProperty> properties) throws PaymentControlApiException {
-            return new DefaultPriorPaymentControlResult(false, null, null, null, getAdjustedProperties(properties, newPriorCallProperties, removedPriorCallProperties));
+            return new DefaultPriorPaymentControlResult(false, account.getPaymentMethodId(), null, null, getAdjustedProperties(properties, newPriorCallProperties, removedPriorCallProperties));
         }
 
         @Override
@@ -247,7 +248,7 @@ public class TestPaymentGatewayApiWithPaymentControl extends PaymentTestSuiteNoD
             return new DefaultFailureCallResult(null, getAdjustedProperties(properties, newOnResultProperties, removedOnResultProperties));
         }
 
-        private static Iterable<PluginProperty> getAdjustedProperties(final Iterable<PluginProperty> input, final Iterable<PluginProperty> newProperties, final Iterable<PluginProperty> removedProperties) {
+        private Iterable<PluginProperty> getAdjustedProperties(final Iterable<PluginProperty> input, final Iterable<PluginProperty> newProperties, final Iterable<PluginProperty> removedProperties) {
             final Iterable<PluginProperty> filtered = Iterables.filter(input, new Predicate<PluginProperty>() {
                 @Override
                 public boolean apply(final PluginProperty p) {