killbill-memoizeit

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 ae10edb..b4eb5c2 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
@@ -55,7 +55,7 @@ public class DefaultPaymentGatewayApi extends DefaultApiBase implements PaymentG
     }
 
     @Override
-    public HostedPaymentPageFormDescriptor buildFormDescriptor(final Account account, @Nullable final UUID paymentMethodId, final Iterable<PluginProperty> customFields, final Iterable<PluginProperty> properties, final CallContext callContext) throws PaymentApiException {
+    public HostedPaymentPageFormDescriptor buildFormDescriptor(final Account account, final UUID paymentMethodId, final Iterable<PluginProperty> customFields, final Iterable<PluginProperty> properties, final CallContext callContext) throws PaymentApiException {
         final UUID paymentMethodIdToUse = paymentMethodId != null ? paymentMethodId : account.getPaymentMethodId();
 
         if (paymentMethodId == null) {
@@ -66,7 +66,7 @@ public class DefaultPaymentGatewayApi extends DefaultApiBase implements PaymentG
     }
 
     @Override
-    public HostedPaymentPageFormDescriptor buildFormDescriptorWithPaymentControl(final Account account, @Nullable final UUID paymentMethodId, final Iterable<PluginProperty> customFields, final Iterable<PluginProperty> properties, final PaymentOptions paymentOptions, final CallContext callContext) throws PaymentApiException {
+    public HostedPaymentPageFormDescriptor buildFormDescriptorWithPaymentControl(final Account account, final UUID paymentMethodId, final Iterable<PluginProperty> customFields, final Iterable<PluginProperty> properties, final PaymentOptions paymentOptions, final CallContext callContext) throws PaymentApiException {
 
         return executeWithPaymentControl(account, paymentMethodId, properties, paymentOptions, callContext, new WithPaymentControlCallback<HostedPaymentPageFormDescriptor>() {
             @Override
diff --git a/payment/src/test/java/org/killbill/billing/payment/api/TestPaymentApiWithControl.java b/payment/src/test/java/org/killbill/billing/payment/api/TestPaymentApiWithControl.java
index 5d528a1..34f146d 100644
--- a/payment/src/test/java/org/killbill/billing/payment/api/TestPaymentApiWithControl.java
+++ b/payment/src/test/java/org/killbill/billing/payment/api/TestPaymentApiWithControl.java
@@ -46,7 +46,7 @@ import com.google.inject.Inject;
 public class TestPaymentApiWithControl extends PaymentTestSuiteWithEmbeddedDB {
 
     @Inject
-    private OSGIServiceRegistration<PaymentControlPluginApi> retryPluginRegistry;
+    private OSGIServiceRegistration<PaymentControlPluginApi> controlPluginRegistry;
 
     private Account account;
     private UUID newPaymentMethodId;
@@ -58,7 +58,7 @@ public class TestPaymentApiWithControl extends PaymentTestSuiteWithEmbeddedDB {
         final PaymentMethodPlugin paymentMethodInfo = new DefaultNoOpPaymentMethodPlugin(UUID.randomUUID().toString(), false, null);
         newPaymentMethodId = paymentApi.addPaymentMethod(account, paymentMethodInfo.getExternalPaymentMethodId(), MockPaymentProviderPlugin.PLUGIN_NAME, false, paymentMethodInfo, ImmutableList.<PluginProperty>of(), callContext);
 
-        retryPluginRegistry.registerService(new OSGIServiceDescriptor() {
+        controlPluginRegistry.registerService(new OSGIServiceDescriptor() {
             @Override
             public String getPluginSymbolicName() {
                 return null;
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
new file mode 100644
index 0000000..fb29bff
--- /dev/null
+++ b/payment/src/test/java/org/killbill/billing/payment/api/TestPaymentGatewayApiWithPaymentControl.java
@@ -0,0 +1,257 @@
+/*
+ * 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.payment.api;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+
+import org.killbill.billing.account.api.Account;
+import org.killbill.billing.control.plugin.api.OnFailurePaymentControlResult;
+import org.killbill.billing.control.plugin.api.OnSuccessPaymentControlResult;
+import org.killbill.billing.control.plugin.api.PaymentControlApiException;
+import org.killbill.billing.control.plugin.api.PaymentControlContext;
+import org.killbill.billing.control.plugin.api.PaymentControlPluginApi;
+import org.killbill.billing.control.plugin.api.PriorPaymentControlResult;
+import org.killbill.billing.osgi.api.OSGIServiceDescriptor;
+import org.killbill.billing.osgi.api.OSGIServiceRegistration;
+import org.killbill.billing.payment.PaymentTestSuiteNoDB;
+import org.killbill.billing.payment.retry.DefaultFailureCallResult;
+import org.killbill.billing.payment.retry.DefaultOnSuccessPaymentControlResult;
+import org.killbill.billing.payment.retry.DefaultPriorPaymentControlResult;
+import org.testng.Assert;
+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;
+import com.google.inject.Inject;
+
+public class TestPaymentGatewayApiWithPaymentControl extends PaymentTestSuiteNoDB {
+
+    @Inject
+    private OSGIServiceRegistration<PaymentControlPluginApi> controlPluginRegistry;
+
+    private Account account;
+
+    private PaymentOptions paymentOptions;
+
+    private TestPaymentGatewayApiControlPlugin plugin;
+    private TestPaymentGatewayApiValidationPlugin validationPlugin;
+
+    @BeforeMethod(groups = "fast")
+    public void beforeMethod() throws Exception {
+
+        super.beforeMethod();
+
+        account = testHelper.createTestAccount("arthur@gmail.com", true);
+
+        paymentOptions = new PaymentOptions() {
+            @Override
+            public boolean isExternalPayment() {
+                return false;
+            }
+
+            @Override
+            public List<String> getPaymentControlPluginNames() {
+                return ImmutableList.of(TestPaymentGatewayApiControlPlugin.PLUGIN_NAME, TestPaymentGatewayApiValidationPlugin.VALIDATION_PLUGIN_NAME);
+            }
+        };
+
+        plugin = new TestPaymentGatewayApiControlPlugin();
+
+        controlPluginRegistry.registerService(new OSGIServiceDescriptor() {
+            @Override
+            public String getPluginSymbolicName() {
+                return null;
+            }
+
+            @Override
+            public String getRegistrationName() {
+                return TestPaymentGatewayApiControlPlugin.PLUGIN_NAME;
+            }
+        }, plugin);
+
+        validationPlugin = new TestPaymentGatewayApiValidationPlugin();
+        controlPluginRegistry.registerService(new OSGIServiceDescriptor() {
+            @Override
+            public String getPluginSymbolicName() {
+                return null;
+            }
+
+            @Override
+            public String getRegistrationName() {
+                return TestPaymentGatewayApiValidationPlugin.VALIDATION_PLUGIN_NAME;
+            }
+        }, validationPlugin);
+
+    }
+
+    @Test(groups = "fast")
+    public void testBuildFormDescriptorWithPaymentControl() throws PaymentApiException {
+
+        final List<PluginProperty> initialProperties = new ArrayList<PluginProperty>();
+        initialProperties.add(new PluginProperty("keyA", "valueA", true));
+        initialProperties.add(new PluginProperty("keyB", "valueB", true));
+        initialProperties.add(new PluginProperty("keyC", "valueC", true));
+
+        final List<PluginProperty> priorNewProperties = new ArrayList<PluginProperty>();
+        priorNewProperties.add(new PluginProperty("keyD", "valueD", true));
+        final List<PluginProperty> priorRemovedProperties = new ArrayList<PluginProperty>();
+        priorRemovedProperties.add(new PluginProperty("keyA", "valueA", true));
+        plugin.setPriorCallProperties(priorNewProperties, priorRemovedProperties);
+
+        final List<PluginProperty> onResultNewProperties = new ArrayList<PluginProperty>();
+        onResultNewProperties.add(new PluginProperty("keyE", "valueE", true));
+        final List<PluginProperty> onResultRemovedProperties = new ArrayList<PluginProperty>();
+        onResultRemovedProperties.add(new PluginProperty("keyB", "valueB", true));
+        plugin.setOnResultProperties(onResultNewProperties, onResultRemovedProperties);
+
+        final List<PluginProperty> expectedPriorCallProperties = new ArrayList<PluginProperty>();
+        expectedPriorCallProperties.add(new PluginProperty("keyB", "valueB", true));
+        expectedPriorCallProperties.add(new PluginProperty("keyC", "valueC", true));
+        expectedPriorCallProperties.add(new PluginProperty("keyD", "valueD", true));
+
+        validationPlugin.setExpectedPriorCallProperties(expectedPriorCallProperties);
+
+        final List<PluginProperty> expectedProperties = new ArrayList<PluginProperty>();
+        expectedProperties.add(new PluginProperty("keyC", "valueC", true));
+        expectedProperties.add(new PluginProperty("keyD", "valueD", true));
+        expectedProperties.add(new PluginProperty("keyE", "valueE", true));
+
+        validationPlugin.setExpectedProperties(expectedProperties);
+
+        paymentGatewayApi.buildFormDescriptorWithPaymentControl(account, account.getPaymentMethodId(), ImmutableList.<PluginProperty>of(), initialProperties, paymentOptions, callContext);
+
+    }
+
+    public static class TestPaymentGatewayApiValidationPlugin implements PaymentControlPluginApi {
+
+        public static final String VALIDATION_PLUGIN_NAME = "TestPaymentGatewayApiValidationPlugin";
+
+        private Iterable<PluginProperty> expectedPriorCallProperties;
+        private Iterable<PluginProperty> expectedProperties;
+
+        public TestPaymentGatewayApiValidationPlugin() {
+            this.expectedPriorCallProperties = ImmutableList.of();
+            this.expectedProperties = ImmutableList.of();
+        }
+
+        public void setExpectedProperties(final Iterable<PluginProperty> expectedProperties) {
+            this.expectedProperties = expectedProperties;
+        }
+
+        public void setExpectedPriorCallProperties(final List<PluginProperty> expectedPriorCallProperties) {
+            this.expectedPriorCallProperties = expectedPriorCallProperties;
+        }
+
+        @Override
+        public PriorPaymentControlResult priorCall(final PaymentControlContext paymentControlContext, final Iterable<PluginProperty> properties) throws PaymentControlApiException {
+            validate(properties, expectedPriorCallProperties);
+            return new DefaultPriorPaymentControlResult(false);
+        }
+
+        @Override
+        public OnSuccessPaymentControlResult onSuccessCall(final PaymentControlContext paymentControlContext, final Iterable<PluginProperty> properties) throws PaymentControlApiException {
+            validate(properties, expectedProperties);
+            return new DefaultOnSuccessPaymentControlResult();
+        }
+
+        @Override
+        public OnFailurePaymentControlResult onFailureCall(final PaymentControlContext paymentControlContext, final Iterable<PluginProperty> properties) throws PaymentControlApiException {
+            validate(properties, expectedProperties);
+            return new DefaultFailureCallResult();
+        }
+
+        private static void validate(final Iterable<PluginProperty> properties, final Iterable<PluginProperty> expected) {
+            Assert.assertEquals(Iterables.size(properties), Iterables.size(expected), "Got " + Iterables.size(properties) + "properties" + ", expected " + Iterables.size(expected));
+
+            for (final PluginProperty curExpected : expected) {
+                Assert.assertTrue(Iterables.any(properties, new Predicate<PluginProperty>() {
+                    @Override
+                    public boolean apply(final PluginProperty input) {
+                        return input.getKey().equals(curExpected.getKey()) && input.getValue().equals(curExpected.getValue());
+
+                    }
+                }), "Cannot find expected property" + curExpected.getKey());
+            }
+        }
+
+    }
+
+    public static class TestPaymentGatewayApiControlPlugin implements PaymentControlPluginApi {
+
+        public static final String PLUGIN_NAME = "TestPaymentGatewayApiControlPlugin";
+
+        private Iterable<PluginProperty> newPriorCallProperties;
+        private Iterable<PluginProperty> removedPriorCallProperties;
+
+        private Iterable<PluginProperty> newOnResultProperties;
+        private Iterable<PluginProperty> removedOnResultProperties;
+
+        public TestPaymentGatewayApiControlPlugin() {
+            this.newPriorCallProperties = ImmutableList.of();
+            this.removedPriorCallProperties = ImmutableList.of();
+            this.newOnResultProperties = ImmutableList.of();
+            this.removedOnResultProperties = ImmutableList.of();
+        }
+
+        public void setPriorCallProperties(final Iterable<PluginProperty> newPriorCallProperties, final Iterable<PluginProperty> removedPriorCallProperties) {
+            this.newPriorCallProperties = newPriorCallProperties;
+            this.removedPriorCallProperties = removedPriorCallProperties;
+        }
+
+        public void setOnResultProperties(final Iterable<PluginProperty> newOnResultProperties, final Iterable<PluginProperty> removedOnResultProperties) {
+            this.newOnResultProperties = newOnResultProperties;
+            this.removedOnResultProperties = removedOnResultProperties;
+        }
+
+        @Override
+        public PriorPaymentControlResult priorCall(final PaymentControlContext paymentControlContext, final Iterable<PluginProperty> properties) throws PaymentControlApiException {
+            return new DefaultPriorPaymentControlResult(false, null, null, null, getAdjustedProperties(properties, newPriorCallProperties, removedPriorCallProperties));
+        }
+
+        @Override
+        public OnSuccessPaymentControlResult onSuccessCall(final PaymentControlContext paymentControlContext, final Iterable<PluginProperty> properties) throws PaymentControlApiException {
+            return new DefaultOnSuccessPaymentControlResult(getAdjustedProperties(properties, newOnResultProperties, removedOnResultProperties));
+        }
+
+        @Override
+        public OnFailurePaymentControlResult onFailureCall(final PaymentControlContext paymentControlContext, final Iterable<PluginProperty> properties) throws PaymentControlApiException {
+            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) {
+            final Iterable<PluginProperty> filtered = Iterables.filter(input, new Predicate<PluginProperty>() {
+                @Override
+                public boolean apply(final PluginProperty p) {
+                    final boolean toBeRemoved = Iterables.any(removedProperties, new Predicate<PluginProperty>() {
+                        @Override
+                        public boolean apply(final PluginProperty a) {
+                            return a.getKey().equals(p.getKey()) && a.getValue().equals(p.getValue());
+                        }
+                    });
+                    return !toBeRemoved;
+                }
+            });
+            return Iterables.concat(filtered, newProperties);
+        }
+    }
+
+}
diff --git a/payment/src/test/java/org/killbill/billing/payment/PaymentTestSuiteNoDB.java b/payment/src/test/java/org/killbill/billing/payment/PaymentTestSuiteNoDB.java
index 778f279..9c19560 100644
--- a/payment/src/test/java/org/killbill/billing/payment/PaymentTestSuiteNoDB.java
+++ b/payment/src/test/java/org/killbill/billing/payment/PaymentTestSuiteNoDB.java
@@ -23,6 +23,7 @@ import org.killbill.billing.account.api.AccountInternalApi;
 import org.killbill.billing.invoice.api.InvoiceInternalApi;
 import org.killbill.billing.osgi.api.OSGIServiceRegistration;
 import org.killbill.billing.payment.api.PaymentApi;
+import org.killbill.billing.payment.api.PaymentGatewayApi;
 import org.killbill.billing.payment.core.PaymentMethodProcessor;
 import org.killbill.billing.payment.core.PaymentProcessor;
 import org.killbill.billing.payment.core.PluginControlPaymentProcessor;
@@ -62,6 +63,8 @@ public abstract class PaymentTestSuiteNoDB extends GuicyKillbillTestSuiteNoDB {
     @Inject
     protected PaymentApi paymentApi;
     @Inject
+    protected PaymentGatewayApi paymentGatewayApi;
+    @Inject
     protected AccountInternalApi accountInternalApi;
     @Inject
     protected TestPaymentHelper testHelper;
diff --git a/payment/src/test/java/org/killbill/billing/payment/PaymentTestSuiteWithEmbeddedDB.java b/payment/src/test/java/org/killbill/billing/payment/PaymentTestSuiteWithEmbeddedDB.java
index 81c4813..1ab3f64 100644
--- a/payment/src/test/java/org/killbill/billing/payment/PaymentTestSuiteWithEmbeddedDB.java
+++ b/payment/src/test/java/org/killbill/billing/payment/PaymentTestSuiteWithEmbeddedDB.java
@@ -23,6 +23,7 @@ import org.killbill.billing.account.api.AccountInternalApi;
 import org.killbill.billing.invoice.api.InvoiceInternalApi;
 import org.killbill.billing.osgi.api.OSGIServiceRegistration;
 import org.killbill.billing.payment.api.PaymentApi;
+import org.killbill.billing.payment.api.PaymentGatewayApi;
 import org.killbill.billing.payment.core.PaymentProcessor;
 import org.killbill.billing.payment.core.PaymentMethodProcessor;
 import org.killbill.billing.payment.core.sm.PaymentStateMachineHelper;
@@ -60,6 +61,8 @@ public abstract class PaymentTestSuiteWithEmbeddedDB extends GuicyKillbillTestSu
     @Inject
     protected PaymentApi paymentApi;
     @Inject
+    protected PaymentGatewayApi paymentGatewayApi;
+    @Inject
     protected AccountInternalApi accountApi;
     @Inject
     protected PaymentStateMachineHelper paymentSMHelper;