killbill-aplcache

Details

diff --git a/payment/src/test/java/org/killbill/billing/payment/api/TestPaymentApi.java b/payment/src/test/java/org/killbill/billing/payment/api/TestPaymentApi.java
index d6e293e..8b36812 100644
--- a/payment/src/test/java/org/killbill/billing/payment/api/TestPaymentApi.java
+++ b/payment/src/test/java/org/killbill/billing/payment/api/TestPaymentApi.java
@@ -189,8 +189,72 @@ public class TestPaymentApi extends PaymentTestSuiteWithEmbeddedDB {
         assertEquals(payment.getTransactions().get(0).getTransactionType(), TransactionType.PURCHASE);
         assertNotNull(payment.getTransactions().get(0).getGatewayErrorMsg());
         assertNotNull(payment.getTransactions().get(0).getGatewayErrorCode());
+
+        final Payment payment2 = paymentApi.createPurchase(account, account.getPaymentMethodId(), null, requestedAmount, Currency.AED, paymentExternalKey, transactionExternalKey,
+                                                           ImmutableList.<PluginProperty>of(), callContext);
+
+        assertEquals(payment2.getExternalKey(), paymentExternalKey);
+        assertEquals(payment2.getTransactions().get(0).getExternalKey(), transactionExternalKey);
+        assertEquals(payment2.getTransactions().get(0).getTransactionStatus(), TransactionStatus.PAYMENT_FAILURE);
+        assertEquals(payment2.getTransactions().get(0).getTransactionType(), TransactionType.PURCHASE);
+
+        assertEquals(payment2.getTransactions().get(1).getExternalKey(), transactionExternalKey);
+        assertEquals(payment2.getTransactions().get(1).getTransactionStatus(), TransactionStatus.SUCCESS);
+        assertEquals(payment2.getTransactions().get(1).getTransactionType(), TransactionType.PURCHASE);
+
     }
 
+
+    @Test(groups = "slow")
+    public void testCreateCancelledPurchase() throws PaymentApiException {
+
+        final BigDecimal requestedAmount = BigDecimal.TEN;
+
+        final String paymentExternalKey = "hgh3";
+        final String transactionExternalKey = "hgh3sss";
+
+        mockPaymentProviderPlugin.makeNextPaymentFailWithCancellation();
+
+        final Payment payment = paymentApi.createPurchase(account, account.getPaymentMethodId(), null, requestedAmount, Currency.AED, paymentExternalKey, transactionExternalKey,
+                                                          ImmutableList.<PluginProperty>of(), callContext);
+
+        assertEquals(payment.getExternalKey(), paymentExternalKey);
+        assertEquals(payment.getPaymentMethodId(), account.getPaymentMethodId());
+        assertEquals(payment.getAccountId(), account.getId());
+        assertEquals(payment.getAuthAmount().compareTo(BigDecimal.ZERO), 0);
+        assertEquals(payment.getCapturedAmount().compareTo(BigDecimal.ZERO), 0);
+        assertEquals(payment.getPurchasedAmount().compareTo(BigDecimal.ZERO), 0);
+        assertEquals(payment.getRefundedAmount().compareTo(BigDecimal.ZERO), 0);
+        assertEquals(payment.getCurrency(), Currency.AED);
+
+        assertEquals(payment.getTransactions().size(), 1);
+        assertEquals(payment.getTransactions().get(0).getExternalKey(), transactionExternalKey);
+        assertEquals(payment.getTransactions().get(0).getPaymentId(), payment.getId());
+        assertEquals(payment.getTransactions().get(0).getAmount().compareTo(requestedAmount), 0);
+        assertEquals(payment.getTransactions().get(0).getCurrency(), Currency.AED);
+        assertEquals(payment.getTransactions().get(0).getProcessedAmount().compareTo(BigDecimal.ZERO), 0);
+        assertEquals(payment.getTransactions().get(0).getProcessedCurrency(), Currency.AED);
+
+        assertEquals(payment.getTransactions().get(0).getTransactionStatus(), TransactionStatus.PLUGIN_FAILURE);
+        assertEquals(payment.getTransactions().get(0).getTransactionType(), TransactionType.PURCHASE);
+        assertNotNull(payment.getTransactions().get(0).getGatewayErrorMsg());
+        assertNotNull(payment.getTransactions().get(0).getGatewayErrorCode());
+
+        final Payment payment2 = paymentApi.createPurchase(account, account.getPaymentMethodId(), null, requestedAmount, Currency.AED, paymentExternalKey, transactionExternalKey,
+                                                           ImmutableList.<PluginProperty>of(), callContext);
+
+        assertEquals(payment2.getExternalKey(), paymentExternalKey);
+        assertEquals(payment2.getTransactions().get(0).getExternalKey(), transactionExternalKey);
+        assertEquals(payment2.getTransactions().get(0).getTransactionStatus(), TransactionStatus.PLUGIN_FAILURE);
+        assertEquals(payment2.getTransactions().get(0).getTransactionType(), TransactionType.PURCHASE);
+
+        assertEquals(payment2.getTransactions().get(1).getExternalKey(), transactionExternalKey);
+        assertEquals(payment2.getTransactions().get(1).getTransactionStatus(), TransactionStatus.SUCCESS);
+        assertEquals(payment2.getTransactions().get(1).getTransactionType(), TransactionType.PURCHASE);
+
+    }
+
+
     @Test(groups = "slow")
     public void testCreateSuccessAuthCapture() throws PaymentApiException {
 
@@ -414,6 +478,82 @@ public class TestPaymentApi extends PaymentTestSuiteWithEmbeddedDB {
 
 
     @Test(groups = "slow")
+    public void testCreateCancelledPurchaseWithPaymentControl() throws PaymentApiException, InvoiceApiException, EventBusException {
+
+        final BigDecimal requestedAmount = BigDecimal.TEN;
+        final UUID subscriptionId = UUID.randomUUID();
+        final UUID bundleId = UUID.randomUUID();
+        final LocalDate now = clock.getUTCToday();
+
+        final Invoice invoice = testHelper.createTestInvoice(account, now, Currency.USD);
+
+        final String paymentExternalKey = invoice.getId().toString();
+        final String transactionExternalKey = "hgjhgjgjhg33";
+
+        mockPaymentProviderPlugin.makeNextPaymentFailWithCancellation();
+
+        invoice.addInvoiceItem(new MockRecurringInvoiceItem(invoice.getId(), account.getId(),
+                                                            subscriptionId,
+                                                            bundleId,
+                                                            "test plan", "test phase", null,
+                                                            now,
+                                                            now.plusMonths(1),
+                                                            requestedAmount,
+                                                            new BigDecimal("1.0"),
+                                                            Currency.USD));
+        try {
+            paymentApi.createPurchaseWithPaymentControl(account, account.getPaymentMethodId(), null, requestedAmount, Currency.USD, paymentExternalKey, transactionExternalKey,
+                                                        createPropertiesForInvoice(invoice), INVOICE_PAYMENT, callContext);
+        } catch (final PaymentApiException expected) {
+            assertTrue(true);
+        }
+
+
+        final List<Payment> accountPayments = paymentApi.getAccountPayments(account.getId(), false, ImmutableList.<PluginProperty>of(), callContext);
+        assertEquals(accountPayments.size(), 1);
+        final Payment payment = accountPayments.get(0);
+        assertEquals(payment.getExternalKey(), paymentExternalKey);
+        assertEquals(payment.getPaymentMethodId(), account.getPaymentMethodId());
+        assertEquals(payment.getAccountId(), account.getId());
+        assertEquals(payment.getAuthAmount().compareTo(BigDecimal.ZERO), 0);
+        assertEquals(payment.getCapturedAmount().compareTo(BigDecimal.ZERO), 0);
+        assertEquals(payment.getPurchasedAmount().compareTo(BigDecimal.ZERO), 0);
+        assertEquals(payment.getRefundedAmount().compareTo(BigDecimal.ZERO), 0);
+        assertEquals(payment.getCurrency(), Currency.USD);
+
+        assertEquals(payment.getTransactions().size(), 1);
+        assertEquals(payment.getTransactions().get(0).getExternalKey(), transactionExternalKey);
+        assertEquals(payment.getTransactions().get(0).getPaymentId(), payment.getId());
+        assertEquals(payment.getTransactions().get(0).getAmount().compareTo(requestedAmount), 0);
+        assertEquals(payment.getTransactions().get(0).getCurrency(), Currency.USD);
+        assertEquals(payment.getTransactions().get(0).getProcessedAmount().compareTo(BigDecimal.ZERO), 0);
+        assertEquals(payment.getTransactions().get(0).getProcessedCurrency(), Currency.USD);
+
+        assertEquals(payment.getTransactions().get(0).getTransactionStatus(), TransactionStatus.PLUGIN_FAILURE);
+        assertEquals(payment.getTransactions().get(0).getTransactionType(), TransactionType.PURCHASE);
+
+        // Make sure we can retry and that works
+        paymentApi.createPurchaseWithPaymentControl(account, account.getPaymentMethodId(), null, requestedAmount, Currency.USD, paymentExternalKey, transactionExternalKey,
+                                                    createPropertiesForInvoice(invoice), INVOICE_PAYMENT, callContext);
+
+
+        final List<Payment> accountPayments2 = paymentApi.getAccountPayments(account.getId(), false, ImmutableList.<PluginProperty>of(), callContext);
+        assertEquals(accountPayments2.size(), 1);
+        final Payment payment2 = accountPayments2.get(0);
+        assertEquals(payment2.getTransactions().size(), 2);
+
+        assertEquals(payment2.getTransactions().get(0).getExternalKey(), transactionExternalKey);
+        assertEquals(payment2.getTransactions().get(0).getTransactionStatus(), TransactionStatus.PLUGIN_FAILURE);
+        assertEquals(payment2.getTransactions().get(0).getTransactionType(), TransactionType.PURCHASE);
+
+        assertEquals(payment2.getTransactions().get(1).getExternalKey(), transactionExternalKey);
+        assertEquals(payment2.getTransactions().get(1).getTransactionStatus(), TransactionStatus.SUCCESS);
+        assertEquals(payment2.getTransactions().get(1).getTransactionType(), TransactionType.PURCHASE);
+
+    }
+
+
+    @Test(groups = "slow")
     public void testCreateAbortedPurchaseWithPaymentControl() throws InvoiceApiException, EventBusException {
 
         final BigDecimal requestedAmount = BigDecimal.TEN;
diff --git a/payment/src/test/java/org/killbill/billing/payment/provider/MockPaymentProviderPlugin.java b/payment/src/test/java/org/killbill/billing/payment/provider/MockPaymentProviderPlugin.java
index cc8c6e1..05d300f 100644
--- a/payment/src/test/java/org/killbill/billing/payment/provider/MockPaymentProviderPlugin.java
+++ b/payment/src/test/java/org/killbill/billing/payment/provider/MockPaymentProviderPlugin.java
@@ -68,9 +68,10 @@ public class MockPaymentProviderPlugin implements PaymentPluginApi {
 
     public static final String PLUGIN_NAME = "__NO_OP__";
 
-    private final AtomicBoolean makeNextInvoiceFailWithError = new AtomicBoolean(false);
-    private final AtomicBoolean makeNextInvoiceFailWithException = new AtomicBoolean(false);
-    private final AtomicBoolean makeAllInvoicesFailWithError = new AtomicBoolean(false);
+    private final AtomicBoolean makeNextPaymentFailWithError = new AtomicBoolean(false);
+    private final AtomicBoolean makeNextPaymentFailWithCancellation = new AtomicBoolean(false);
+    private final AtomicBoolean makeNextPaymentFailWithException = new AtomicBoolean(false);
+    private final AtomicBoolean makeAllPaymentsFailWithError = new AtomicBoolean(false);
     private final AtomicInteger makePluginWaitSomeMilliseconds = new AtomicInteger(0);
     private final AtomicReference<BigDecimal> overrideNextProcessedAmount = new AtomicReference<BigDecimal>();
     private final AtomicReference<Currency> overrideNextProcessedCurrency = new AtomicReference<Currency>();
@@ -194,9 +195,10 @@ public class MockPaymentProviderPlugin implements PaymentPluginApi {
     }
 
     public void clear() {
-        makeNextInvoiceFailWithException.set(false);
-        makeAllInvoicesFailWithError.set(false);
-        makeNextInvoiceFailWithError.set(false);
+        makeNextPaymentFailWithException.set(false);
+        makeAllPaymentsFailWithError.set(false);
+        makeNextPaymentFailWithError.set(false);
+        makeNextPaymentFailWithCancellation.set(false);
         makePluginWaitSomeMilliseconds.set(0);
         overrideNextProcessedAmount.set(null);
         paymentMethods.clear();
@@ -206,15 +208,19 @@ public class MockPaymentProviderPlugin implements PaymentPluginApi {
     }
 
     public void makeNextPaymentFailWithError() {
-        makeNextInvoiceFailWithError.set(true);
+        makeNextPaymentFailWithError.set(true);
+    }
+
+    public void makeNextPaymentFailWithCancellation() {
+        makeNextPaymentFailWithCancellation.set(true);
     }
 
     public void makeNextPaymentFailWithException() {
-        makeNextInvoiceFailWithException.set(true);
+        makeNextPaymentFailWithException.set(true);
     }
 
     public void makeAllInvoicesFailWithError(final boolean failure) {
-        makeAllInvoicesFailWithError.set(failure);
+        makeAllPaymentsFailWithError.set(failure);
     }
 
     public void makePluginWaitSomeMilliseconds(final int milliseconds) {
@@ -368,7 +374,7 @@ public class MockPaymentProviderPlugin implements PaymentPluginApi {
             }
         }
 
-        if (makeNextInvoiceFailWithException.getAndSet(false)) {
+        if (makeNextPaymentFailWithException.getAndSet(false)) {
             throw new PaymentPluginApiException("", "test error");
         }
 
@@ -382,8 +388,12 @@ public class MockPaymentProviderPlugin implements PaymentPluginApi {
         final PaymentPluginStatus status;
         if (paymentPluginStatusOverride != null && paymentPluginStatusOverride.getValue() != null) {
             status = PaymentPluginStatus.valueOf(paymentPluginStatusOverride.getValue().toString());
+        } else if (makeAllPaymentsFailWithError.get() || makeNextPaymentFailWithError.getAndSet(false)) {
+            status = PaymentPluginStatus.ERROR;
+        } else if (makeNextPaymentFailWithCancellation.getAndSet(false)) {
+            status = PaymentPluginStatus.CANCELED;
         } else {
-            status = (makeAllInvoicesFailWithError.get() || makeNextInvoiceFailWithError.getAndSet(false)) ? PaymentPluginStatus.ERROR : PaymentPluginStatus.PROCESSED;
+            status = PaymentPluginStatus.PROCESSED;
         }
         final String errorCode = status == PaymentPluginStatus.PROCESSED ? "" : GATEWAY_ERROR_CODE;
         final String error = status == PaymentPluginStatus.PROCESSED ? "" : GATEWAY_ERROR;
diff --git a/profiles/killbill/src/main/java/org/killbill/billing/server/security/TenantFilter.java b/profiles/killbill/src/main/java/org/killbill/billing/server/security/TenantFilter.java
index 3c6c6ce..7f2a2bb 100644
--- a/profiles/killbill/src/main/java/org/killbill/billing/server/security/TenantFilter.java
+++ b/profiles/killbill/src/main/java/org/killbill/billing/server/security/TenantFilter.java
@@ -131,6 +131,8 @@ public class TenantFilter implements Filter {
                     isTenantCreationRequest(path, httpMethod) ||
                     // Retrieve user permissions should not require tenant info since this is cross tenants
                     isPermissionRequest(path, httpMethod) ||
+                    // Node request are cross tenant
+                    isNodeCreationRequest(path, httpMethod) ||
                     // Metrics servlets
                     isMetricsRequest(path, httpMethod) ||
                     // See KillBillShiroWebModule#CorsBasicHttpAuthenticationFilter
@@ -157,6 +159,10 @@ public class TenantFilter implements Filter {
         return JaxrsResource.TENANTS_PATH.equals(path) && "POST".equals(httpMethod);
     }
 
+    private boolean isNodeCreationRequest(final String path, final String httpMethod) {
+        return JaxrsResource.NODES_INFO_PATH.equals(path) && "POST".equals(httpMethod);
+    }
+
     private boolean isMetricsRequest(final String path, final String httpMethod) {
         return KillbillGuiceListener.METRICS_SERVLETS_PATHS.contains(path) && "GET".equals(httpMethod);
     }