killbill-aplcache
Changes
payment/src/main/java/org/killbill/billing/payment/core/sm/control/CompletionControlOperation.java 1(+1 -0)
payment/src/main/java/org/killbill/billing/payment/core/sm/control/ControlPluginRunner.java 58(+39 -19)
payment/src/main/java/org/killbill/billing/payment/core/sm/control/OperationControlCallback.java 5(+5 -0)
payment/src/main/java/org/killbill/billing/payment/retry/DefaultPriorPaymentControlResult.java 14(+11 -3)
payment/src/test/java/org/killbill/billing/payment/api/TestPaymentGatewayApiWithPaymentControl.java 2(+1 -1)
Details
diff --git a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestPaymentWithControl.java b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestPaymentWithControl.java
index 7879aad..60bdf05 100644
--- a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestPaymentWithControl.java
+++ b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestPaymentWithControl.java
@@ -271,6 +271,12 @@ public class TestPaymentWithControl extends TestIntegrationBase {
public UUID getAdjustedPaymentMethodId() {
return adjustedPaymentMethodId;
}
+
+ @Override
+ public String getAdjustedPluginName() {
+ return null;
+ }
+
@Override
public Iterable<PluginProperty> getAdjustedPluginProperties() {
return null;
diff --git a/payment/src/main/java/org/killbill/billing/payment/api/DefaultPaymentApi.java b/payment/src/main/java/org/killbill/billing/payment/api/DefaultPaymentApi.java
index e114d2e..8c55462 100644
--- a/payment/src/main/java/org/killbill/billing/payment/api/DefaultPaymentApi.java
+++ b/payment/src/main/java/org/killbill/billing/payment/api/DefaultPaymentApi.java
@@ -991,6 +991,17 @@ public class DefaultPaymentApi extends DefaultApiBase implements PaymentApi {
}
@Override
+ public UUID addPaymentMethodWithPaymentControl(final Account account, final String paymentMethodExternalKey, final String pluginName, final boolean setDefault, final PaymentMethodPlugin paymentMethodInfo, final Iterable<PluginProperty> properties, final PaymentOptions paymentOptions, final CallContext context) throws PaymentApiException {
+ final List<String> paymentControlPluginNames = toPaymentControlPluginNames(paymentOptions, context);
+ if (paymentControlPluginNames.isEmpty()) {
+ return addPaymentMethod(account, paymentMethodExternalKey, pluginName, setDefault, paymentMethodInfo, properties, context);
+ }
+
+ return paymentMethodProcessor.addPaymentMethodWithControl(paymentMethodExternalKey, pluginName, account, setDefault, paymentMethodInfo, properties,
+ paymentControlPluginNames, context, internalCallContextFactory.createInternalCallContext(account.getId(), context));
+ }
+
+ @Override
public List<PaymentMethod> getAccountPaymentMethods(final UUID accountId, final boolean includedInactive, final boolean withPluginInfo, final Iterable<PluginProperty> properties, final TenantContext context)
throws PaymentApiException {
return paymentMethodProcessor.getPaymentMethods(includedInactive, withPluginInfo, properties, context, internalCallContextFactory.createInternalTenantContext(accountId, context));
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 26bce39..55cddc7 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
@@ -147,6 +147,7 @@ public class DefaultPaymentGatewayApi extends DefaultApiBase implements PaymentG
null,
null,
null,
+ null,
PaymentApiType.HPP,
null,
HPPType.BUILD_FORM_DESCRIPTOR,
@@ -174,6 +175,7 @@ public class DefaultPaymentGatewayApi extends DefaultApiBase implements PaymentG
null,
null,
null,
+ null,
PaymentApiType.HPP,
null,
HPPType.BUILD_FORM_DESCRIPTOR,
@@ -194,6 +196,7 @@ public class DefaultPaymentGatewayApi extends DefaultApiBase implements PaymentG
null,
null,
null,
+ null,
PaymentApiType.HPP,
null,
HPPType.BUILD_FORM_DESCRIPTOR,
diff --git a/payment/src/main/java/org/killbill/billing/payment/core/PaymentMethodProcessor.java b/payment/src/main/java/org/killbill/billing/payment/core/PaymentMethodProcessor.java
index c30581d..b37085c 100644
--- a/payment/src/main/java/org/killbill/billing/payment/core/PaymentMethodProcessor.java
+++ b/payment/src/main/java/org/killbill/billing/payment/core/PaymentMethodProcessor.java
@@ -23,6 +23,7 @@ import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.UUID;
+import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;
import javax.annotation.Nullable;
@@ -33,12 +34,17 @@ import org.killbill.billing.account.api.AccountApiException;
import org.killbill.billing.account.api.AccountInternalApi;
import org.killbill.billing.callcontext.InternalCallContext;
import org.killbill.billing.callcontext.InternalTenantContext;
+import org.killbill.billing.control.plugin.api.PaymentApiType;
+import org.killbill.billing.control.plugin.api.PaymentControlApiException;
+import org.killbill.billing.control.plugin.api.PriorPaymentControlResult;
import org.killbill.billing.invoice.api.InvoiceInternalApi;
import org.killbill.billing.payment.api.DefaultPaymentMethod;
import org.killbill.billing.payment.api.PaymentApiException;
import org.killbill.billing.payment.api.PaymentMethod;
import org.killbill.billing.payment.api.PaymentMethodPlugin;
import org.killbill.billing.payment.api.PluginProperty;
+import org.killbill.billing.payment.core.sm.control.ControlPluginRunner;
+import org.killbill.billing.payment.core.sm.control.PaymentControlApiAbortException;
import org.killbill.billing.payment.dao.PaymentDao;
import org.killbill.billing.payment.dao.PaymentMethodModelDao;
import org.killbill.billing.payment.dispatcher.PluginDispatcher;
@@ -50,6 +56,7 @@ import org.killbill.billing.payment.provider.DefaultNoOpPaymentMethodPlugin;
import org.killbill.billing.payment.provider.DefaultPaymentMethodInfoPlugin;
import org.killbill.billing.payment.provider.ExternalPaymentProviderPlugin;
import org.killbill.billing.tag.TagInternalApi;
+import org.killbill.billing.util.PluginProperties;
import org.killbill.billing.util.UUIDs;
import org.killbill.billing.util.callcontext.CallContext;
import org.killbill.billing.util.callcontext.InternalCallContextFactory;
@@ -65,6 +72,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.base.Function;
+import com.google.common.base.Joiner;
import com.google.common.base.MoreObjects;
import com.google.common.base.Predicate;
import com.google.common.collect.Collections2;
@@ -80,9 +88,12 @@ import static org.killbill.billing.util.entity.dao.DefaultPaginationHelper.getEn
public class PaymentMethodProcessor extends ProcessorBase {
private static final Logger log = LoggerFactory.getLogger(PaymentMethodProcessor.class);
+ private static final Joiner JOINER = Joiner.on(", ");
private final PluginDispatcher<UUID> uuidPluginNotificationDispatcher;
+ private final ControlPluginRunner controlPluginRunner;
+
private final PaymentConfig paymentConfig;
@Inject
@@ -94,11 +105,13 @@ public class PaymentMethodProcessor extends ProcessorBase {
final GlobalLocker locker,
final PaymentConfig paymentConfig,
final PaymentExecutors executors,
+ final ControlPluginRunner controlPluginRunner,
final InternalCallContextFactory internalCallContextFactory,
final Clock clock) {
super(paymentPluginServiceRegistration, accountInternalApi, paymentDao, tagUserApi, locker, internalCallContextFactory, invoiceApi, clock);
final long paymentPluginTimeoutSec = TimeUnit.SECONDS.convert(paymentConfig.getPaymentPluginTimeout().getPeriod(), paymentConfig.getPaymentPluginTimeout().getUnit());
this.paymentConfig = paymentConfig;
+ this.controlPluginRunner = controlPluginRunner;
this.uuidPluginNotificationDispatcher = new PluginDispatcher<UUID>(paymentPluginTimeoutSec, executors);
}
@@ -145,7 +158,6 @@ public class PaymentMethodProcessor extends ProcessorBase {
return PluginDispatcher.createPluginDispatcherReturnType(pm.getId());
}
-
private void validateUniqueExternalPaymentMethod(final UUID accountId, final String pluginName) throws PaymentApiException {
if (ExternalPaymentProviderPlugin.PLUGIN_NAME.equals(pluginName)) {
final List<PaymentMethodModelDao> accountPaymentMethods = paymentDao.getPaymentMethods(context);
@@ -163,6 +175,119 @@ public class PaymentMethodProcessor extends ProcessorBase {
uuidPluginNotificationDispatcher);
}
+ public UUID addPaymentMethodWithControl(final String paymentMethodExternalKey, final String paymentPluginServiceName, final Account account,
+ final boolean setDefault, final PaymentMethodPlugin paymentMethodProps, final Iterable<PluginProperty> properties,
+ final List<String> paymentControlPluginNames, final CallContext callContext, final InternalCallContext context) throws PaymentApiException {
+ final Iterable<PluginProperty> mergedProperties = PluginProperties.merge(paymentMethodProps.getProperties(), properties);
+ return executeWithPaymentMethodControl(paymentPluginServiceName, account, mergedProperties, paymentControlPluginNames, callContext, uuidPluginNotificationDispatcher, new WithPaymentMethodControlCallback<UUID>() {
+ @Override
+ public UUID doPaymentMethodApiOperation(final String adjustedPaymentPluginServiceName, final Iterable<PluginProperty> adjustedPluginProperties) throws PaymentApiException {
+ if (adjustedPaymentPluginServiceName == null) {
+ return addPaymentMethod(paymentMethodExternalKey, paymentPluginServiceName, account, setDefault, paymentMethodProps, properties, callContext, context);
+ } else {
+ return addPaymentMethod(paymentMethodExternalKey, adjustedPaymentPluginServiceName, account, setDefault, paymentMethodProps, properties, callContext, context);
+ }
+ }
+ });
+ }
+
+
+ private interface WithPaymentMethodControlCallback<T> {
+ T doPaymentMethodApiOperation(final String adjustedPluginName, final Iterable<PluginProperty> adjustedPluginProperties) throws PaymentApiException;
+ }
+
+ private <T> T executeWithPaymentMethodControl(final String paymentPluginServiceName,
+ final Account account,
+ final Iterable<PluginProperty> properties,
+ final List<String> paymentControlPluginNames,
+ final CallContext callContext,
+ final PluginDispatcher<T> pluginDispatcher,
+ final WithPaymentMethodControlCallback<T> callback) throws PaymentApiException {
+
+ return dispatchWithExceptionHandling(account,
+ JOINER.join(paymentControlPluginNames),
+ new Callable<PluginDispatcherReturnType<T>>() {
+ @Override
+ public PluginDispatcherReturnType<T> call() throws Exception {
+ final PriorPaymentControlResult priorCallResult;
+ try {
+ priorCallResult = controlPluginRunner.executePluginPriorCalls(account,
+ null,
+ paymentPluginServiceName,
+ null,
+ null,
+ null,
+ null,
+ null,
+ PaymentApiType.PAYMENT_METHOD,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ true,
+ paymentControlPluginNames,
+ properties,
+ callContext);
+
+ } catch (final PaymentControlApiAbortException e) {
+ throw new PaymentApiException(ErrorCode.PAYMENT_PLUGIN_API_ABORTED, e.getPluginName());
+ } catch (final PaymentControlApiException e) {
+ throw new PaymentApiException(e, ErrorCode.PAYMENT_PLUGIN_EXCEPTION, e);
+ }
+
+ try {
+ final T result = callback.doPaymentMethodApiOperation(priorCallResult.getAdjustedPluginName(), priorCallResult.getAdjustedPluginProperties());
+ controlPluginRunner.executePluginOnSuccessCalls(account,
+ null,
+ priorCallResult.getAdjustedPluginName(),
+ null,
+ null,
+ null,
+ null,
+ null,
+ PaymentApiType.PAYMENT_METHOD,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ true,
+ paymentControlPluginNames,
+ priorCallResult.getAdjustedPluginProperties(),
+ callContext);
+ return PluginDispatcher.createPluginDispatcherReturnType(result);
+ } catch (final PaymentApiException e) {
+ controlPluginRunner.executePluginOnFailureCalls(account,
+ null,
+ priorCallResult.getAdjustedPluginName(),
+ null,
+ null,
+ null,
+ null,
+ null,
+ PaymentApiType.PAYMENT_METHOD,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ true,
+ paymentControlPluginNames,
+ priorCallResult.getAdjustedPluginProperties(),
+ callContext);
+ throw e;
+ }
+ }
+ },
+ pluginDispatcher);
+ }
+
+
+
private String retrieveActualPaymentMethodExternalKey(final Account account, final PaymentMethod pm, final PaymentPluginApi pluginApi, final Iterable<PluginProperty> properties, final TenantContext callContext, final InternalCallContext context) {
// If the user specified an external key, use it
if (pm.getExternalKey() != null) {
diff --git a/payment/src/main/java/org/killbill/billing/payment/core/sm/control/CompletionControlOperation.java b/payment/src/main/java/org/killbill/billing/payment/core/sm/control/CompletionControlOperation.java
index 9ba0ab2..7c503ea 100644
--- a/payment/src/main/java/org/killbill/billing/payment/core/sm/control/CompletionControlOperation.java
+++ b/payment/src/main/java/org/killbill/billing/payment/core/sm/control/CompletionControlOperation.java
@@ -67,6 +67,7 @@ public class CompletionControlOperation extends OperationControlCallback {
final PaymentTransactionModelDao transaction = paymentStateContext.getPaymentTransactionModelDao();
final PaymentControlContext updatedPaymentControlContext = new DefaultPaymentControlContext(paymentStateContext.getAccount(),
paymentStateContext.getPaymentMethodId(),
+ null,
paymentStateControlContext.getAttemptId(),
transaction.getPaymentId(),
paymentStateContext.getPaymentExternalKey(),
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 c132bea..15da0e2 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
@@ -59,6 +59,7 @@ public class ControlPluginRunner {
public PriorPaymentControlResult executePluginPriorCalls(final Account account,
final UUID paymentMethodId,
+ final String pluginName,
final UUID paymentAttemptId,
final UUID paymentId,
final String paymentExternalKey,
@@ -76,15 +77,17 @@ public class ControlPluginRunner {
final Iterable<PluginProperty> pluginProperties,
final CallContext callContext) throws PaymentControlApiException {
// Return as soon as the first plugin aborts, or the last result for the last plugin
- PriorPaymentControlResult prevResult = new DefaultPriorPaymentControlResult(false, amount, currency, paymentMethodId, pluginProperties);
+ PriorPaymentControlResult prevResult = new DefaultPriorPaymentControlResult(false, amount, currency, paymentMethodId, null, pluginProperties);
// Those values are adjusted prior each call with the result of what previous call to plugin returned
UUID inputPaymentMethodId = paymentMethodId;
+ String inputPaymentMethodName = pluginName;
BigDecimal inputAmount = amount;
Currency inputCurrency = currency;
Iterable<PluginProperty> inputPluginProperties = pluginProperties;
PaymentControlContext inputPaymentControlContext = new DefaultPaymentControlContext(account,
paymentMethodId,
+ pluginName,
paymentAttemptId,
paymentId,
paymentExternalKey,
@@ -100,16 +103,16 @@ public class ControlPluginRunner {
isApiPayment,
callContext);
- for (final String pluginName : paymentControlPluginNames) {
- final PaymentControlPluginApi plugin = paymentControlPluginRegistry.getServiceForName(pluginName);
+ for (final String controlPluginName : paymentControlPluginNames) {
+ final PaymentControlPluginApi plugin = paymentControlPluginRegistry.getServiceForName(controlPluginName);
if (plugin == null) {
// First call to plugin, we log warn, if plugin is not registered
- log.warn("Skipping unknown payment control plugin {} when fetching results", pluginName);
+ log.warn("Skipping unknown payment control plugin {} when fetching results", controlPluginName);
continue;
}
- log.debug("Calling priorCall of plugin {}", pluginName);
+ log.debug("Calling priorCall of plugin {}", controlPluginName);
prevResult = plugin.priorCall(inputPaymentControlContext, inputPluginProperties);
- log.debug("Successful executed priorCall of plugin {}", pluginName);
+ log.debug("Successful executed priorCall of plugin {}", controlPluginName);
if (prevResult == null) {
// Nothing returned by the plugin
continue;
@@ -118,6 +121,9 @@ public class ControlPluginRunner {
if (prevResult.getAdjustedPaymentMethodId() != null) {
inputPaymentMethodId = prevResult.getAdjustedPaymentMethodId();
}
+ if (prevResult.getAdjustedPluginName() != null) {
+ inputPaymentMethodName = prevResult.getAdjustedPluginName();
+ }
if (prevResult.getAdjustedAmount() != null) {
inputAmount = prevResult.getAdjustedAmount();
}
@@ -128,10 +134,11 @@ public class ControlPluginRunner {
inputPluginProperties = prevResult.getAdjustedPluginProperties();
}
if (prevResult.isAborted()) {
- throw new PaymentControlApiAbortException(pluginName);
+ throw new PaymentControlApiAbortException(controlPluginName);
}
inputPaymentControlContext = new DefaultPaymentControlContext(account,
inputPaymentMethodId,
+ controlPluginName,
paymentAttemptId,
paymentId,
paymentExternalKey,
@@ -148,12 +155,13 @@ public class ControlPluginRunner {
callContext);
}
// Rebuild latest result to include inputPluginProperties
- prevResult = new DefaultPriorPaymentControlResult(prevResult != null && prevResult.isAborted(), inputPaymentMethodId, inputAmount, inputCurrency, inputPluginProperties);
+ prevResult = new DefaultPriorPaymentControlResult(prevResult != null && prevResult.isAborted(), inputPaymentMethodId, inputPaymentMethodName, inputAmount, inputCurrency, inputPluginProperties);
return prevResult;
}
public OnSuccessPaymentControlResult executePluginOnSuccessCalls(final Account account,
final UUID paymentMethodId,
+ final String pluginName,
final UUID paymentAttemptId,
final UUID paymentId,
final String paymentExternalKey,
@@ -173,6 +181,7 @@ public class ControlPluginRunner {
final PaymentControlContext inputPaymentControlContext = new DefaultPaymentControlContext(account,
paymentMethodId,
+ pluginName,
paymentAttemptId,
paymentId,
paymentExternalKey,
@@ -189,13 +198,13 @@ public class ControlPluginRunner {
callContext);
Iterable<PluginProperty> inputPluginProperties = pluginProperties;
- for (final String pluginName : paymentControlPluginNames) {
- final PaymentControlPluginApi plugin = paymentControlPluginRegistry.getServiceForName(pluginName);
+ for (final String controlPluginName : paymentControlPluginNames) {
+ final PaymentControlPluginApi plugin = paymentControlPluginRegistry.getServiceForName(controlPluginName);
if (plugin != null) {
try {
- log.debug("Calling onSuccessCall of plugin {}", pluginName);
+ log.debug("Calling onSuccessCall of plugin {}", controlPluginName);
final OnSuccessPaymentControlResult result = plugin.onSuccessCall(inputPaymentControlContext, inputPluginProperties);
- log.debug("Successful executed onSuccessCall of plugin {}", pluginName);
+ log.debug("Successful executed onSuccessCall of plugin {}", controlPluginName);
if (result == null) {
// Nothing returned by the plugin
continue;
@@ -206,9 +215,9 @@ public class ControlPluginRunner {
}
// Exceptions from the control plugins are ignored (and logged) because the semantics on what to do are undefined.
} catch (final PaymentControlApiException e) {
- log.warn("Error during onSuccessCall for plugin='{}', paymentExternalKey='{}'", pluginName, inputPaymentControlContext.getPaymentExternalKey(), e);
+ log.warn("Error during onSuccessCall for plugin='{}', paymentExternalKey='{}'", controlPluginName, inputPaymentControlContext.getPaymentExternalKey(), e);
} catch (final RuntimeException e) {
- log.warn("Error during onSuccessCall for plugin='{}', paymentExternalKey='{}'", pluginName, inputPaymentControlContext.getPaymentExternalKey(), e);
+ log.warn("Error during onSuccessCall for plugin='{}', paymentExternalKey='{}'", controlPluginName, inputPaymentControlContext.getPaymentExternalKey(), e);
}
}
}
@@ -217,6 +226,7 @@ public class ControlPluginRunner {
public OnFailurePaymentControlResult executePluginOnFailureCalls(final Account account,
final UUID paymentMethodId,
+ final String pluginName,
final UUID paymentAttemptId,
final UUID paymentId,
final String paymentExternalKey,
@@ -236,6 +246,7 @@ public class ControlPluginRunner {
final PaymentControlContext inputPaymentControlContext = new DefaultPaymentControlContext(account,
paymentMethodId,
+ pluginName,
paymentAttemptId,
paymentId,
paymentExternalKey,
@@ -254,13 +265,13 @@ public class ControlPluginRunner {
DateTime candidate = null;
Iterable<PluginProperty> inputPluginProperties = pluginProperties;
- for (final String pluginName : paymentControlPluginNames) {
- final PaymentControlPluginApi plugin = paymentControlPluginRegistry.getServiceForName(pluginName);
+ for (final String controlPluginName : paymentControlPluginNames) {
+ final PaymentControlPluginApi plugin = paymentControlPluginRegistry.getServiceForName(controlPluginName);
if (plugin != null) {
try {
- log.debug("Calling onSuccessCall of plugin {}", pluginName);
+ log.debug("Calling onSuccessCall of plugin {}", controlPluginName);
final OnFailurePaymentControlResult result = plugin.onFailureCall(inputPaymentControlContext, inputPluginProperties);
- log.debug("Successful executed onSuccessCall of plugin {}", pluginName);
+ log.debug("Successful executed onSuccessCall of plugin {}", controlPluginName);
if (result == null) {
// Nothing returned by the plugin
continue;
@@ -277,7 +288,7 @@ public class ControlPluginRunner {
}
} catch (final PaymentControlApiException e) {
- log.warn("Error during onFailureCall for plugin='{}', paymentExternalKey='{}'", pluginName, inputPaymentControlContext.getPaymentExternalKey(), e);
+ log.warn("Error during onFailureCall for plugin='{}', paymentExternalKey='{}'", controlPluginName, inputPaymentControlContext.getPaymentExternalKey(), e);
return new DefaultFailureCallResult(candidate, inputPluginProperties);
}
}
@@ -289,6 +300,7 @@ public class ControlPluginRunner {
private final Account account;
private final UUID paymentMethodId;
+ private final String pluginName;
private final UUID attemptId;
private final UUID paymentId;
private final String paymentExternalKey;
@@ -305,6 +317,7 @@ public class ControlPluginRunner {
public DefaultPaymentControlContext(final Account account,
final UUID paymentMethodId,
+ @Nullable String pluginName,
final UUID attemptId,
@Nullable final UUID paymentId,
final String paymentExternalKey,
@@ -322,6 +335,7 @@ public class ControlPluginRunner {
super(account.getId(), callContext.getTenantId(), callContext.getUserName(), callContext.getCallOrigin(), callContext.getUserType(), callContext.getReasonCode(), callContext.getComments(), callContext.getUserToken(), callContext.getCreatedDate(), callContext.getUpdatedDate());
this.account = account;
this.paymentMethodId = paymentMethodId;
+ this.pluginName = pluginName;
this.attemptId = attemptId;
this.paymentId = paymentId;
this.paymentExternalKey = paymentExternalKey;
@@ -383,6 +397,11 @@ public class ControlPluginRunner {
}
@Override
+ public String getPaymentPluginName() {
+ return pluginName;
+ }
+
+ @Override
public UUID getPaymentId() {
return paymentId;
}
@@ -416,6 +435,7 @@ public class ControlPluginRunner {
return "DefaultPaymentControlContext{" +
"account=" + account +
", paymentMethodId=" + paymentMethodId +
+ ", pluginName=" + pluginName +
", attemptId=" + attemptId +
", paymentId=" + paymentId +
", paymentExternalKey='" + paymentExternalKey + '\'' +
diff --git a/payment/src/main/java/org/killbill/billing/payment/core/sm/control/OperationControlCallback.java b/payment/src/main/java/org/killbill/billing/payment/core/sm/control/OperationControlCallback.java
index a562e32..65348af 100644
--- a/payment/src/main/java/org/killbill/billing/payment/core/sm/control/OperationControlCallback.java
+++ b/payment/src/main/java/org/killbill/billing/payment/core/sm/control/OperationControlCallback.java
@@ -88,6 +88,7 @@ public abstract class OperationControlCallback extends OperationCallbackBase<Pay
final PaymentControlContext paymentControlContext = new DefaultPaymentControlContext(paymentStateContext.getAccount(),
paymentStateContext.getPaymentMethodId(),
+ null,
paymentStateControlContext.getAttemptId(),
paymentStateContext.getPaymentId(),
paymentStateContext.getPaymentExternalKey(),
@@ -123,6 +124,7 @@ public abstract class OperationControlCallback extends OperationCallbackBase<Pay
success = transaction.getTransactionStatus() == TransactionStatus.SUCCESS || transaction.getTransactionStatus() == TransactionStatus.PENDING;
final PaymentControlContext updatedPaymentControlContext = new DefaultPaymentControlContext(paymentStateContext.getAccount(),
paymentStateContext.getPaymentMethodId(),
+ null,
paymentStateControlContext.getAttemptId(),
result.getId(),
result.getExternalKey(),
@@ -173,6 +175,7 @@ public abstract class OperationControlCallback extends OperationCallbackBase<Pay
final PriorPaymentControlResult result = controlPluginRunner.executePluginPriorCalls(paymentStateContext.getAccount(),
paymentControlContextArg.getPaymentMethodId(),
+ null,
paymentStateControlContext.getAttemptId(),
paymentStateContext.getPaymentId(),
paymentStateContext.getPaymentExternalKey(),
@@ -199,6 +202,7 @@ public abstract class OperationControlCallback extends OperationCallbackBase<Pay
// paymentId, paymentExternalKey, transactionAmount, transaction currency are extracted from paymentControlContext which was update from the operation result.
final OnSuccessPaymentControlResult result = controlPluginRunner.executePluginOnSuccessCalls(paymentStateContext.getAccount(),
paymentStateContext.getPaymentMethodId(),
+ null,
paymentStateControlContext.getAttemptId(),
paymentControlContext.getPaymentId(),
paymentControlContext.getPaymentExternalKey(),
@@ -230,6 +234,7 @@ public abstract class OperationControlCallback extends OperationCallbackBase<Pay
final OnFailurePaymentControlResult result = controlPluginRunner.executePluginOnFailureCalls(paymentStateContext.getAccount(),
paymentControlContext.getPaymentMethodId(),
+ null,
paymentStateControlContext.getAttemptId(),
paymentControlContext.getPaymentId(),
paymentControlContext.getPaymentExternalKey(),
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 27ce65b..4ab3d4b 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
@@ -30,22 +30,25 @@ public class DefaultPriorPaymentControlResult implements PriorPaymentControlResu
private final BigDecimal adjustedRetryAmount;
private final Currency adjustedCurrency;
private final UUID adjustedPaymentMethodId;
+ private final String adjustedPaymentPluginName;
private final Iterable<PluginProperty> adjustedPluginProperties;
public DefaultPriorPaymentControlResult(final boolean isAborted,
final BigDecimal adjustedRetryAmount,
final Currency adjustedCurrency,
final UUID adjustedPaymentMethodId,
+ final String adjustedPaymentPluginName,
final Iterable<PluginProperty> adjustedPluginProperties) {
this.isAborted = isAborted;
this.adjustedRetryAmount = adjustedRetryAmount;
this.adjustedCurrency = adjustedCurrency;
this.adjustedPaymentMethodId = adjustedPaymentMethodId;
this.adjustedPluginProperties = adjustedPluginProperties;
+ this.adjustedPaymentPluginName = adjustedPaymentPluginName;
}
public DefaultPriorPaymentControlResult(final boolean isAborted, final BigDecimal adjustedRetryAmount) {
- this(isAborted, adjustedRetryAmount, null, null, null);
+ this(isAborted, adjustedRetryAmount, null, null, null, null);
}
public DefaultPriorPaymentControlResult(final boolean isAborted) {
@@ -53,8 +56,8 @@ public class DefaultPriorPaymentControlResult implements PriorPaymentControlResu
}
- public DefaultPriorPaymentControlResult(final boolean isAborted, final UUID adjustedPaymentMethodId, final BigDecimal adjustedAmount, final Currency adjustedCurrency, final Iterable<PluginProperty> adjustedPluginProperties) {
- this(isAborted, adjustedAmount, adjustedCurrency, adjustedPaymentMethodId, adjustedPluginProperties);
+ public DefaultPriorPaymentControlResult(final boolean isAborted, final UUID adjustedPaymentMethodId, final String adjustedPaymentPluginName, final BigDecimal adjustedAmount, final Currency adjustedCurrency, final Iterable<PluginProperty> adjustedPluginProperties) {
+ this(isAborted, adjustedAmount, adjustedCurrency, adjustedPaymentMethodId, adjustedPaymentPluginName, adjustedPluginProperties);
}
@Override
@@ -78,6 +81,11 @@ public class DefaultPriorPaymentControlResult implements PriorPaymentControlResu
}
@Override
+ public String getAdjustedPluginName() {
+ return adjustedPaymentPluginName;
+ }
+
+ @Override
public Iterable<PluginProperty> getAdjustedPluginProperties() {
return adjustedPluginProperties;
}
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 545fcc4..22fd0b3 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
@@ -645,6 +645,28 @@ public class TestPaymentApiWithControl extends PaymentTestSuiteWithEmbeddedDB {
Currency.USD);
}
+ @Test(groups = "slow")
+ public void testAddPaymentMethodWithControl() throws PaymentApiException {
+ final PaymentMethodPlugin paymentMethodInfo = new DefaultNoOpPaymentMethodPlugin(UUID.randomUUID().toString(), false, null);
+ testPaymentControlPluginApi.setNewPaymentMethodName(MockPaymentProviderPlugin.PLUGIN_NAME);
+ final UUID newPaymentMethodId = paymentApi.addPaymentMethodWithPaymentControl(account, null, "SomeDummyValueToBeChanged", false, paymentMethodInfo, ImmutableList.<PluginProperty>of(), PAYMENT_OPTIONS, callContext);
+
+
+ final PaymentMethod paymentMethod = paymentApi.getPaymentMethodById(newPaymentMethodId, false, false, ImmutableList.<PluginProperty>of(), callContext);
+ Assert.assertEquals(paymentMethod.getPluginName(), MockPaymentProviderPlugin.PLUGIN_NAME);
+
+ final Payment payment = paymentApi.createAuthorizationWithPaymentControl(account, newPaymentMethodId, null, BigDecimal.TEN, Currency.USD, UUID.randomUUID().toString(),
+ UUID.randomUUID().toString(), ImmutableList.<PluginProperty>of(), PAYMENT_OPTIONS, callContext);
+ Assert.assertEquals(payment.getPaymentMethodId(), newPaymentMethodId);
+
+ verifyOnSuccess(payment.getId(),
+ payment.getExternalKey(),
+ payment.getTransactions().get(0).getId(),
+ payment.getTransactions().get(0).getExternalKey(),
+ BigDecimal.TEN,
+ Currency.USD);
+ }
+
private void verifyPriorAndOnSuccess(final UUID paymentId,
final String paymentExternalKey,
final UUID paymentTransactionId,
@@ -830,6 +852,7 @@ public class TestPaymentApiWithControl extends PaymentTestSuiteWithEmbeddedDB {
public static final String PLUGIN_NAME = "TEST_CONTROL_API_PLUGIN_NAME";
private UUID newPaymentMethodId;
+ private String newPaymentMethodName;
private UUID actualPriorCallPaymentId;
private String actualPriorCallPaymentExternalKey;
@@ -856,6 +879,10 @@ public class TestPaymentApiWithControl extends PaymentTestSuiteWithEmbeddedDB {
this.newPaymentMethodId = newPaymentMethodId;
}
+ public void setNewPaymentMethodName(final String newPaymentMethodName) {
+ this.newPaymentMethodName = newPaymentMethodName;
+ }
+
public UUID getActualPriorCallPaymentId() {
return actualPriorCallPaymentId;
}
@@ -959,6 +986,11 @@ public class TestPaymentApiWithControl extends PaymentTestSuiteWithEmbeddedDB {
}
@Override
+ public String getAdjustedPluginName() {
+ return newPaymentMethodName;
+ }
+
+ @Override
public Iterable<PluginProperty> getAdjustedPluginProperties() {
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
index 3aa3554..4698e0d 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
@@ -257,7 +257,7 @@ public class TestPaymentGatewayApiWithPaymentControl extends PaymentTestSuiteNoD
@Override
public PriorPaymentControlResult priorCall(final PaymentControlContext paymentControlContext, final Iterable<PluginProperty> properties) throws PaymentControlApiException {
- return new DefaultPriorPaymentControlResult(aborted, account.getPaymentMethodId(), null, null, getAdjustedProperties(properties, newPriorCallProperties, removedPriorCallProperties));
+ return new DefaultPriorPaymentControlResult(aborted, account.getPaymentMethodId(), null, null, null, getAdjustedProperties(properties, newPriorCallProperties, removedPriorCallProperties));
}
@Override
diff --git a/payment/src/test/java/org/killbill/billing/payment/core/sm/control/TestControlPluginRunner.java b/payment/src/test/java/org/killbill/billing/payment/core/sm/control/TestControlPluginRunner.java
index 80cb640..1e114e4 100644
--- a/payment/src/test/java/org/killbill/billing/payment/core/sm/control/TestControlPluginRunner.java
+++ b/payment/src/test/java/org/killbill/billing/payment/core/sm/control/TestControlPluginRunner.java
@@ -54,6 +54,7 @@ public class TestControlPluginRunner extends PaymentTestSuiteNoDB {
final PriorPaymentControlResult paymentControlResult = controlPluginRunner.executePluginPriorCalls(account,
paymentMethodId,
null,
+ null,
paymentId,
paymentExternalKey,
paymentTransactionId,
diff --git a/payment/src/test/java/org/killbill/billing/payment/provider/MockPaymentControlProviderPlugin.java b/payment/src/test/java/org/killbill/billing/payment/provider/MockPaymentControlProviderPlugin.java
index f451943..f7c949e 100644
--- a/payment/src/test/java/org/killbill/billing/payment/provider/MockPaymentControlProviderPlugin.java
+++ b/payment/src/test/java/org/killbill/billing/payment/provider/MockPaymentControlProviderPlugin.java
@@ -77,7 +77,7 @@ public class MockPaymentControlProviderPlugin implements PaymentControlPluginApi
} else if (exception instanceof RuntimeException) {
throw (RuntimeException) exception;
}
- return new DefaultPriorPaymentControlResult(isAborted, adjustedPaymentMethodId, null, null, null);
+ return new DefaultPriorPaymentControlResult(isAborted, adjustedPaymentMethodId, null, null, null, null);
}
@Override