killbill-aplcache

payment: pass HPP form properties to control plugins The

1/5/2016 10:16:28 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 595b3a9..f115032 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
@@ -1,6 +1,6 @@
 /*
- * Copyright 2014-2015 Groupon, Inc
- * Copyright 2014-2015 The Billing Project, LLC
+ * Copyright 2014-2016 Groupon, Inc
+ * Copyright 2014-2016 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
@@ -38,6 +38,7 @@ import org.killbill.billing.payment.dispatcher.PluginDispatcher;
 import org.killbill.billing.payment.dispatcher.PluginDispatcher.PluginDispatcherReturnType;
 import org.killbill.billing.payment.plugin.api.GatewayNotification;
 import org.killbill.billing.payment.plugin.api.HostedPaymentPageFormDescriptor;
+import org.killbill.billing.util.PluginProperties;
 import org.killbill.billing.util.callcontext.CallContext;
 import org.killbill.billing.util.callcontext.InternalCallContextFactory;
 import org.killbill.billing.util.config.PaymentConfig;
@@ -78,10 +79,11 @@ public class DefaultPaymentGatewayApi extends DefaultApiBase implements PaymentG
 
     @Override
     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, paymentPluginFormDispatcher, new WithPaymentControlCallback<HostedPaymentPageFormDescriptor>() {
+        final Iterable<PluginProperty> mergedProperties = PluginProperties.merge(customFields, properties);
+        return executeWithPaymentControl(account, paymentMethodId, mergedProperties, paymentOptions, callContext, paymentPluginFormDispatcher, new WithPaymentControlCallback<HostedPaymentPageFormDescriptor>() {
             @Override
             public HostedPaymentPageFormDescriptor doPaymentGatewayApiOperation(final UUID adjustedPaymentMethodId, final Iterable<PluginProperty> adjustedPluginProperties) throws PaymentApiException {
-                return buildFormDescriptor(false, account, adjustedPaymentMethodId, customFields, adjustedPluginProperties, callContext);
+                return buildFormDescriptor(false, account, adjustedPaymentMethodId, mergedProperties, adjustedPluginProperties, callContext);
             }
         });
     }
diff --git a/util/src/main/java/org/killbill/billing/util/PluginProperties.java b/util/src/main/java/org/killbill/billing/util/PluginProperties.java
new file mode 100644
index 0000000..c7e4e4e
--- /dev/null
+++ b/util/src/main/java/org/killbill/billing/util/PluginProperties.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2016 Groupon, Inc
+ * Copyright 2016 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.util;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.annotation.Nullable;
+
+import org.killbill.billing.payment.api.PluginProperty;
+
+import com.google.common.collect.ImmutableList;
+
+public abstract class PluginProperties {
+
+    // Last one has precedence
+    public static Iterable<PluginProperty> merge(final Iterable<PluginProperty>... propertiesLists) {
+        return buildPluginProperties(toMap(propertiesLists));
+    }
+
+    // Last one has precedence
+    public static Map<String, Object> toMap(final Iterable<PluginProperty>... propertiesLists) {
+        final Map<String, Object> mergedProperties = new HashMap<String, Object>();
+        for (final Iterable<PluginProperty> propertiesList : propertiesLists) {
+            for (final PluginProperty pluginProperty : propertiesList) {
+                if (pluginProperty.getKey() != null) {
+                    mergedProperties.put(pluginProperty.getKey(), pluginProperty.getValue());
+                }
+            }
+        }
+        return mergedProperties;
+    }
+
+    public static List<PluginProperty> buildPluginProperties(@Nullable final Map<String, Object> data) {
+        final ImmutableList.Builder<PluginProperty> propertiesBuilder = ImmutableList.<PluginProperty>builder();
+        if (data != null) {
+            for (final String key : data.keySet()) {
+                final PluginProperty property = new PluginProperty(key, data.get(key), false);
+                propertiesBuilder.add(property);
+            }
+        }
+        return propertiesBuilder.build();
+    }
+}
diff --git a/util/src/test/java/org/killbill/billing/util/TestPluginProperties.java b/util/src/test/java/org/killbill/billing/util/TestPluginProperties.java
new file mode 100644
index 0000000..0978e16
--- /dev/null
+++ b/util/src/test/java/org/killbill/billing/util/TestPluginProperties.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2016 Groupon, Inc
+ * Copyright 2016 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.util;
+
+import java.util.List;
+import java.util.Map;
+
+import org.killbill.billing.payment.api.PluginProperty;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import com.google.common.base.Function;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Ordering;
+
+public class TestPluginProperties extends UtilTestSuiteNoDB {
+
+    private final List<PluginProperty> pluginProperties1 = PluginProperties.buildPluginProperties(ImmutableMap.<String, Object>of("foo", "bar",
+                                                                                                                                  "baz", 12L));
+    private final List<PluginProperty> pluginProperties2 = PluginProperties.buildPluginProperties(ImmutableMap.<String, Object>of("foo", "override",
+                                                                                                                                  "baz2", "something else"));
+
+    @Test(groups = "fast")
+    public void testMerge() throws Exception {
+        final List<PluginProperty> pluginPropertiesRaw = ImmutableList.<PluginProperty>copyOf(PluginProperties.merge(pluginProperties1, pluginProperties2));
+
+        final List<PluginProperty> pluginProperties = sort(pluginPropertiesRaw);
+
+        Assert.assertEquals(pluginProperties.size(), 3);
+        Assert.assertEquals(pluginProperties.get(0).getKey(), "baz");
+        Assert.assertEquals(pluginProperties.get(0).getValue(), (Long) 12L);
+        Assert.assertFalse(pluginProperties.get(0).getIsUpdatable());
+        Assert.assertEquals(pluginProperties.get(1).getKey(), "baz2");
+        Assert.assertEquals(pluginProperties.get(1).getValue(), "something else");
+        Assert.assertFalse(pluginProperties.get(1).getIsUpdatable());
+        Assert.assertEquals(pluginProperties.get(2).getKey(), "foo");
+        Assert.assertEquals(pluginProperties.get(2).getValue(), "override");
+        Assert.assertFalse(pluginProperties.get(2).getIsUpdatable());
+    }
+
+    @Test(groups = "fast")
+    public void testToMap() throws Exception {
+        final Map<String, Object> properties = PluginProperties.toMap(pluginProperties1, pluginProperties2);
+        Assert.assertEquals(properties.get("baz"), (Long) 12L);
+        Assert.assertEquals(properties.get("baz2"), "something else");
+        Assert.assertEquals(properties.get("foo"), "override");
+    }
+
+    @Test(groups = "fast")
+    public void testBuildPluginProperties() throws Exception {
+        Assert.assertEquals(pluginProperties1.size(), 2);
+        Assert.assertEquals(pluginProperties1.get(0).getKey(), "foo");
+        Assert.assertEquals(pluginProperties1.get(0).getValue(), "bar");
+        Assert.assertFalse(pluginProperties1.get(0).getIsUpdatable());
+        Assert.assertEquals(pluginProperties1.get(1).getKey(), "baz");
+        Assert.assertEquals(pluginProperties1.get(1).getValue(), (Long) 12L);
+        Assert.assertFalse(pluginProperties1.get(1).getIsUpdatable());
+    }
+
+    private List<PluginProperty> sort(final Iterable<PluginProperty> pluginProperties) {
+        return Ordering.natural()
+                       .onResultOf(new Function<PluginProperty, String>() {
+                           @Override
+                           public String apply(final PluginProperty pluginProperty) {
+                               return pluginProperty.getKey();
+                           }
+                       })
+                       .immutableSortedCopy(pluginProperties);
+    }
+}