killbill-uncached
Changes
payment/src/main/java/org/killbill/billing/payment/core/PaymentTransactionInfoPluginConverter.java 72(+72 -0)
payment/src/main/java/org/killbill/billing/payment/core/sm/payments/PaymentEnteringStateCallback.java 31(+3 -28)
payment/src/main/java/org/killbill/billing/payment/core/sm/payments/PaymentOperation.java 33(+8 -25)
Details
diff --git a/payment/src/main/java/org/killbill/billing/payment/core/janitor/ErroredPaymentTask.java b/payment/src/main/java/org/killbill/billing/payment/core/janitor/ErroredPaymentTask.java
index 7b376ae..596323f 100644
--- a/payment/src/main/java/org/killbill/billing/payment/core/janitor/ErroredPaymentTask.java
+++ b/payment/src/main/java/org/killbill/billing/payment/core/janitor/ErroredPaymentTask.java
@@ -30,6 +30,7 @@ import org.killbill.billing.catalog.api.Currency;
import org.killbill.billing.osgi.api.OSGIServiceRegistration;
import org.killbill.billing.payment.api.PluginProperty;
import org.killbill.billing.payment.api.TransactionStatus;
+import org.killbill.billing.payment.core.PaymentTransactionInfoPluginConverter;
import org.killbill.billing.payment.core.sm.payments.PaymentEnteringStateCallback;
import org.killbill.billing.payment.core.sm.PaymentStateMachineHelper;
import org.killbill.billing.payment.core.sm.PluginRoutingPaymentAutomatonRunner;
@@ -114,7 +115,7 @@ public class ErroredPaymentTask extends CompletionTaskBase<PaymentModelDao> {
}
// Compute new transactionStatus based on pluginInfo state; and if that did not change, bail early.
- final TransactionStatus transactionStatus = PaymentEnteringStateCallback.paymentPluginStatusToTransactionStatus(pluginErroredTransaction);
+ final TransactionStatus transactionStatus = PaymentTransactionInfoPluginConverter.toTransactionStatus(pluginErroredTransaction);
if (transactionStatus == unknownTransaction.getTransactionStatus()) {
return;
}
diff --git a/payment/src/main/java/org/killbill/billing/payment/core/PaymentTransactionInfoPluginConverter.java b/payment/src/main/java/org/killbill/billing/payment/core/PaymentTransactionInfoPluginConverter.java
new file mode 100644
index 0000000..d60d540
--- /dev/null
+++ b/payment/src/main/java/org/killbill/billing/payment/core/PaymentTransactionInfoPluginConverter.java
@@ -0,0 +1,72 @@
+/*
+ * 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.core;
+
+import javax.annotation.Nullable;
+
+import org.killbill.automaton.OperationResult;
+import org.killbill.billing.payment.api.TransactionStatus;
+import org.killbill.billing.payment.plugin.api.PaymentTransactionInfoPlugin;
+
+//
+// Conversion between the plugin result to the payment state and transaction status
+//
+public class PaymentTransactionInfoPluginConverter {
+
+ public static TransactionStatus toTransactionStatus(@Nullable final PaymentTransactionInfoPlugin paymentTransactionInfoPlugin) {
+ //
+ // paymentTransactionInfoPlugin when we got an exception from the plugin, or if the plugin behaves badly
+ // and decides to return null; in all cases this is seen as a PLUGIN_FAILURE
+ //
+ if (paymentTransactionInfoPlugin == null || paymentTransactionInfoPlugin.getStatus() == null) {
+ return TransactionStatus.PLUGIN_FAILURE;
+ }
+
+ switch (paymentTransactionInfoPlugin.getStatus()) {
+ case PROCESSED:
+ return TransactionStatus.SUCCESS;
+ case PENDING:
+ return TransactionStatus.PENDING;
+ case ERROR:
+ return TransactionStatus.PAYMENT_FAILURE;
+ // This will be picked up by Janitor to figure out what really happened and correct the state if needed
+ case UNDEFINED:
+ default:
+ return TransactionStatus.UNKNOWN;
+ }
+ }
+
+ public static OperationResult toOperationResult(@Nullable final PaymentTransactionInfoPlugin paymentTransactionInfoPlugin) {
+ if (paymentTransactionInfoPlugin == null || paymentTransactionInfoPlugin.getStatus() == null) {
+ return OperationResult.EXCEPTION;
+ }
+
+ switch (paymentTransactionInfoPlugin.getStatus()) {
+ case PROCESSED:
+ return OperationResult.SUCCESS;
+ case PENDING:
+ return OperationResult.PENDING;
+ case ERROR:
+ return OperationResult.FAILURE;
+ // Might change later if Janitor fixes the state
+ case UNDEFINED:
+ default:
+ return OperationResult.EXCEPTION;
+ }
+ }
+}
diff --git a/payment/src/main/java/org/killbill/billing/payment/core/sm/PaymentAutomatonDAOHelper.java b/payment/src/main/java/org/killbill/billing/payment/core/sm/PaymentAutomatonDAOHelper.java
index 0ec8b99..8db48a9 100644
--- a/payment/src/main/java/org/killbill/billing/payment/core/sm/PaymentAutomatonDAOHelper.java
+++ b/payment/src/main/java/org/killbill/billing/payment/core/sm/PaymentAutomatonDAOHelper.java
@@ -101,7 +101,7 @@ public class PaymentAutomatonDAOHelper {
paymentStateContext.setOnLeavingStateExistingTransactions(existingTransactions);
}
- public void processPaymentInfoPlugin(final TransactionStatus paymentStatus, @Nullable final PaymentTransactionInfoPlugin paymentInfoPlugin,
+ public void processPaymentInfoPlugin(final TransactionStatus transactionStatus, @Nullable final PaymentTransactionInfoPlugin paymentInfoPlugin,
final String currentPaymentStateName) {
final BigDecimal processedAmount = paymentInfoPlugin == null ? null : paymentInfoPlugin.getAmount();
final Currency processedCurrency = paymentInfoPlugin == null ? null : paymentInfoPlugin.getCurrency();
@@ -115,7 +115,7 @@ public class PaymentAutomatonDAOHelper {
currentPaymentStateName,
lastSuccessPaymentState,
paymentStateContext.getPaymentTransactionModelDao().getId(),
- paymentStatus,
+ transactionStatus,
processedAmount,
processedCurrency,
gatewayErrorCode,
diff --git a/payment/src/main/java/org/killbill/billing/payment/core/sm/payments/PaymentEnteringStateCallback.java b/payment/src/main/java/org/killbill/billing/payment/core/sm/payments/PaymentEnteringStateCallback.java
index f61ef7c..5b340aa 100644
--- a/payment/src/main/java/org/killbill/billing/payment/core/sm/payments/PaymentEnteringStateCallback.java
+++ b/payment/src/main/java/org/killbill/billing/payment/core/sm/payments/PaymentEnteringStateCallback.java
@@ -28,6 +28,7 @@ import org.killbill.billing.events.BusInternalEvent;
import org.killbill.billing.payment.api.DefaultPaymentErrorEvent;
import org.killbill.billing.payment.api.PaymentApiException;
import org.killbill.billing.payment.api.TransactionStatus;
+import org.killbill.billing.payment.core.PaymentTransactionInfoPluginConverter;
import org.killbill.billing.payment.core.sm.PaymentAutomatonDAOHelper;
import org.killbill.billing.payment.core.sm.PaymentStateContext;
import org.killbill.billing.payment.plugin.api.PaymentTransactionInfoPlugin;
@@ -53,8 +54,8 @@ public abstract class PaymentEnteringStateCallback implements EnteringStateCallb
// If the transaction was not created -- for instance we had an exception in leavingState callback then we bail; if not, then update state:
if (paymentStateContext.getPaymentTransactionModelDao() != null && paymentStateContext.getPaymentTransactionModelDao().getId() != null) {
- final PaymentTransactionInfoPlugin paymentInfoPlugin = paymentStateContext.getPaymentInfoPlugin();
- final TransactionStatus transactionStatus = paymentPluginStatusToTransactionStatus(paymentInfoPlugin);
+ final PaymentTransactionInfoPlugin paymentInfoPlugin = paymentStateContext.getPaymentTransactionInfoPlugin();
+ final TransactionStatus transactionStatus = PaymentTransactionInfoPluginConverter.toTransactionStatus(paymentInfoPlugin);
// The bus event will be posted from the transaction
daoHelper.processPaymentInfoPlugin(transactionStatus, paymentInfoPlugin, newState.getName());
} else if (!paymentStateContext.isApiPayment()) {
@@ -76,30 +77,4 @@ public abstract class PaymentEnteringStateCallback implements EnteringStateCallb
}
}
}
-
- public static TransactionStatus paymentPluginStatusToTransactionStatus(@Nullable final PaymentTransactionInfoPlugin paymentInfoPlugin) {
-
- //
- // paymentInfoPlugin when we got an exception from the plugin, or if the plugin behaves badly
- // and decides to return null; in all cases this is seen as a PLUGIN_FAILURE
- //
- if (paymentInfoPlugin == null || paymentInfoPlugin.getStatus() == null) {
- return TransactionStatus.PLUGIN_FAILURE;
- }
-
- //
- // The plugin returned a status or it timedout and we added manually a UNKNOWN status to end up here
- //
- switch (paymentInfoPlugin.getStatus()) {
- case PROCESSED:
- return TransactionStatus.SUCCESS;
- case PENDING:
- return TransactionStatus.PENDING;
- case ERROR:
- return TransactionStatus.PAYMENT_FAILURE;
- case UNDEFINED:
- default:
- return TransactionStatus.UNKNOWN;
- }
- }
}
diff --git a/payment/src/main/java/org/killbill/billing/payment/core/sm/payments/PaymentOperation.java b/payment/src/main/java/org/killbill/billing/payment/core/sm/payments/PaymentOperation.java
index 70c2159..d072424 100644
--- a/payment/src/main/java/org/killbill/billing/payment/core/sm/payments/PaymentOperation.java
+++ b/payment/src/main/java/org/killbill/billing/payment/core/sm/payments/PaymentOperation.java
@@ -29,6 +29,7 @@ import org.killbill.billing.ErrorCode;
import org.killbill.billing.payment.api.PaymentApiException;
import org.killbill.billing.payment.api.TransactionStatus;
import org.killbill.billing.payment.api.TransactionType;
+import org.killbill.billing.payment.core.PaymentTransactionInfoPluginConverter;
import org.killbill.billing.payment.core.ProcessorBase.WithAccountLockCallback;
import org.killbill.billing.payment.core.sm.OperationCallbackBase;
import org.killbill.billing.payment.core.sm.PaymentAutomatonDAOHelper;
@@ -108,7 +109,7 @@ public abstract class PaymentOperation extends OperationCallbackBase<PaymentTran
PaymentPluginStatus.UNDEFINED,
null);
- paymentStateContext.setPaymentInfoPlugin(paymentInfoPlugin);
+ paymentStateContext.setPaymentTransactionInfoPlugin(paymentInfoPlugin);
return new OperationException(e, OperationResult.EXCEPTION);
}
@@ -173,8 +174,8 @@ public abstract class PaymentOperation extends OperationCallbackBase<PaymentTran
// Throws if plugin is ot correctly implemented (e.g returns null result, values,..)
sanityOnPaymentInfoPlugin(paymentInfoPlugin);
- paymentStateContext.setPaymentInfoPlugin(paymentInfoPlugin);
- return processPaymentInfoPlugin();
+ paymentStateContext.setPaymentTransactionInfoPlugin(paymentInfoPlugin);
+ return PaymentTransactionInfoPluginConverter.toOperationResult(paymentStateContext.getPaymentTransactionInfoPlugin());
} else {
final PaymentTransactionInfoPlugin paymentInfoPlugin = new DefaultNoOpPaymentInfoPlugin(paymentStateContext.getPaymentId(),
paymentStateContext.getTransactionId(),
@@ -185,7 +186,7 @@ public abstract class PaymentOperation extends OperationCallbackBase<PaymentTran
paymentStateContext.getPaymentTransactionModelDao().getCreatedDate(),
buildPaymentPluginStatusFromOperationResult(paymentStateContext.getOverridePluginOperationResult()),
null);
- paymentStateContext.setPaymentInfoPlugin(paymentInfoPlugin);
+ paymentStateContext.setPaymentTransactionInfoPlugin(paymentInfoPlugin);
return paymentStateContext.getOverridePluginOperationResult();
}
} catch (final PaymentPluginApiException e) {
@@ -207,37 +208,19 @@ public abstract class PaymentOperation extends OperationCallbackBase<PaymentTran
}
}
- private OperationResult processPaymentInfoPlugin() {
- if (paymentStateContext.getPaymentInfoPlugin() == null || paymentStateContext.getPaymentInfoPlugin().getStatus() == null) {
- return OperationResult.EXCEPTION;
- }
-
- switch (paymentStateContext.getPaymentInfoPlugin().getStatus()) {
- case PROCESSED:
- return OperationResult.SUCCESS;
- case PENDING:
- return OperationResult.PENDING;
- case ERROR:
- return OperationResult.FAILURE;
- case UNDEFINED:
- default:
- return OperationResult.EXCEPTION;
- }
- }
-
private void sanityOnPaymentInfoPlugin(final PaymentTransactionInfoPlugin paymentInfoPlugin) throws PaymentApiException {
if (paymentInfoPlugin == null) {
throw new PaymentApiException(ErrorCode.PAYMENT_PLUGIN_EXCEPTION, "Payment plugin returned a null result");
}
/*
TODO this breaks our tests so test would have to be fixed
- if (paymentInfoPlugin.getKbTransactionPaymentId() == null || !paymentInfoPlugin.getKbTransactionPaymentId().equals(paymentStateContext.getTransactionId())) {
+ if (paymentTransactionInfoPlugin.getKbTransactionPaymentId() == null || !paymentTransactionInfoPlugin.getKbTransactionPaymentId().equals(paymentStateContext.getTransactionId())) {
throw new PaymentApiException(ErrorCode.PAYMENT_PLUGIN_EXCEPTION, "Payment plugin returned invalid kbTransactionId");
}
- if (paymentInfoPlugin.getKbPaymentId() == null || !paymentInfoPlugin.getKbPaymentId().equals(paymentStateContext.getPaymentId())) {
+ if (paymentTransactionInfoPlugin.getKbPaymentId() == null || !paymentTransactionInfoPlugin.getKbPaymentId().equals(paymentStateContext.getPaymentId())) {
throw new PaymentApiException(ErrorCode.PAYMENT_PLUGIN_EXCEPTION, "Payment plugin returned invalid kbPaymentId");
}
- if (paymentInfoPlugin.getTransactionType() == null || !paymentInfoPlugin.getKbPaymentId().equals(paymentStateContext.getTransactionType())) {
+ if (paymentTransactionInfoPlugin.getTransactionType() == null || !paymentTransactionInfoPlugin.getKbPaymentId().equals(paymentStateContext.getTransactionType())) {
throw new PaymentApiException(ErrorCode.PAYMENT_PLUGIN_EXCEPTION, "Payment plugin returned invalid transaction type");
}
*/
diff --git a/payment/src/main/java/org/killbill/billing/payment/core/sm/PaymentStateContext.java b/payment/src/main/java/org/killbill/billing/payment/core/sm/PaymentStateContext.java
index 49b1c11..034fbc4 100644
--- a/payment/src/main/java/org/killbill/billing/payment/core/sm/PaymentStateContext.java
+++ b/payment/src/main/java/org/killbill/billing/payment/core/sm/PaymentStateContext.java
@@ -44,7 +44,7 @@ public class PaymentStateContext {
// Stateful objects created by the callbacks and passed to the other following callbacks in the automaton
protected List<PaymentTransactionModelDao> onLeavingStateExistingTransactions;
protected PaymentTransactionModelDao paymentTransactionModelDao;
- protected PaymentTransactionInfoPlugin paymentInfoPlugin;
+ protected PaymentTransactionInfoPlugin paymentTransactionInfoPlugin;
protected BigDecimal amount;
protected String paymentExternalKey;
protected String paymentTransactionExternalKey;
@@ -120,12 +120,12 @@ public class PaymentStateContext {
this.onLeavingStateExistingTransactions = onLeavingStateExistingTransactions;
}
- public PaymentTransactionInfoPlugin getPaymentInfoPlugin() {
- return paymentInfoPlugin;
+ public PaymentTransactionInfoPlugin getPaymentTransactionInfoPlugin() {
+ return paymentTransactionInfoPlugin;
}
- public void setPaymentInfoPlugin(final PaymentTransactionInfoPlugin paymentInfoPlugin) {
- this.paymentInfoPlugin = paymentInfoPlugin;
+ public void setPaymentTransactionInfoPlugin(final PaymentTransactionInfoPlugin paymentTransactionInfoPlugin) {
+ this.paymentTransactionInfoPlugin = paymentTransactionInfoPlugin;
}
public UUID getPaymentId() {
diff --git a/payment/src/test/java/org/killbill/billing/payment/core/sm/TestPaymentEnteringStateCallback.java b/payment/src/test/java/org/killbill/billing/payment/core/sm/TestPaymentEnteringStateCallback.java
index 806c7a8..c4f53e6 100644
--- a/payment/src/test/java/org/killbill/billing/payment/core/sm/TestPaymentEnteringStateCallback.java
+++ b/payment/src/test/java/org/killbill/billing/payment/core/sm/TestPaymentEnteringStateCallback.java
@@ -89,7 +89,7 @@ public class TestPaymentEnteringStateCallback extends PaymentTestSuiteWithEmbedd
Mockito.when(paymentInfoPlugin.getStatus()).thenReturn(PaymentPluginStatus.PENDING);
Mockito.when(paymentInfoPlugin.getGatewayErrorCode()).thenReturn(UUID.randomUUID().toString().substring(0, 5));
Mockito.when(paymentInfoPlugin.getGatewayError()).thenReturn(UUID.randomUUID().toString());
- paymentStateContext.setPaymentInfoPlugin(paymentInfoPlugin);
+ paymentStateContext.setPaymentTransactionInfoPlugin(paymentInfoPlugin);
// Process the plugin result
callback.enteringState(state, operationCallback, operationResult, leavingStateCallback);
@@ -109,7 +109,7 @@ public class TestPaymentEnteringStateCallback extends PaymentTestSuiteWithEmbedd
public void testEnterStateWithOperationException() throws Exception {
daoHelper.createNewPaymentTransaction();
// Simulate a bug in the plugin - i.e. nothing was returned
- paymentStateContext.setPaymentInfoPlugin(null);
+ paymentStateContext.setPaymentTransactionInfoPlugin(null);
operationResult = OperationResult.EXCEPTION;
callback.enteringState(state, operationCallback, operationResult, leavingStateCallback);
diff --git a/payment/src/test/java/org/killbill/billing/payment/core/sm/TestPaymentOperation.java b/payment/src/test/java/org/killbill/billing/payment/core/sm/TestPaymentOperation.java
index 2e617f1..9f6eb58 100644
--- a/payment/src/test/java/org/killbill/billing/payment/core/sm/TestPaymentOperation.java
+++ b/payment/src/test/java/org/killbill/billing/payment/core/sm/TestPaymentOperation.java
@@ -56,18 +56,18 @@ public class TestPaymentOperation extends PaymentTestSuiteNoDB {
public void testPaymentFailure() throws Exception {
setUp(PaymentPluginStatus.ERROR);
- Assert.assertNull(paymentStateContext.getPaymentInfoPlugin());
+ Assert.assertNull(paymentStateContext.getPaymentTransactionInfoPlugin());
Assert.assertEquals(paymentOperation.doOperationCallback(), OperationResult.FAILURE);
- Assert.assertNotNull(paymentStateContext.getPaymentInfoPlugin());
+ Assert.assertNotNull(paymentStateContext.getPaymentTransactionInfoPlugin());
}
@Test(groups = "fast")
public void testPluginFailure() throws Exception {
setUp(null);
- Assert.assertNull(paymentStateContext.getPaymentInfoPlugin());
+ Assert.assertNull(paymentStateContext.getPaymentTransactionInfoPlugin());
try {
paymentOperation.doOperationCallback();
@@ -76,29 +76,29 @@ public class TestPaymentOperation extends PaymentTestSuiteNoDB {
Assert.assertEquals(e.getOperationResult(), OperationResult.EXCEPTION);
}
- Assert.assertNull(paymentStateContext.getPaymentInfoPlugin());
+ Assert.assertNull(paymentStateContext.getPaymentTransactionInfoPlugin());
}
@Test(groups = "fast")
public void testPaymentPending() throws Exception {
setUp(PaymentPluginStatus.PENDING);
- Assert.assertNull(paymentStateContext.getPaymentInfoPlugin());
+ Assert.assertNull(paymentStateContext.getPaymentTransactionInfoPlugin());
Assert.assertEquals(paymentOperation.doOperationCallback(), OperationResult.PENDING);
- Assert.assertNotNull(paymentStateContext.getPaymentInfoPlugin());
+ Assert.assertNotNull(paymentStateContext.getPaymentTransactionInfoPlugin());
}
@Test(groups = "fast")
public void testPaymentSuccess() throws Exception {
setUp(PaymentPluginStatus.PROCESSED);
- Assert.assertNull(paymentStateContext.getPaymentInfoPlugin());
+ Assert.assertNull(paymentStateContext.getPaymentTransactionInfoPlugin());
Assert.assertEquals(paymentOperation.doOperationCallback(), OperationResult.SUCCESS);
- Assert.assertNotNull(paymentStateContext.getPaymentInfoPlugin());
+ Assert.assertNotNull(paymentStateContext.getPaymentTransactionInfoPlugin());
}
private void setUp(final PaymentPluginStatus paymentPluginStatus) throws Exception {