diff --git a/payment/src/main/java/org/killbill/billing/payment/core/PaymentGatewayProcessor.java b/payment/src/main/java/org/killbill/billing/payment/core/PaymentGatewayProcessor.java
index 37ad942..ffbb208 100644
--- a/payment/src/main/java/org/killbill/billing/payment/core/PaymentGatewayProcessor.java
+++ b/payment/src/main/java/org/killbill/billing/payment/core/PaymentGatewayProcessor.java
@@ -124,26 +124,4 @@ public class PaymentGatewayProcessor extends ProcessorBase {
paymentPluginFormDispatcher);
}
- private static <ReturnType> ReturnType dispatchWithExceptionHandling(@Nullable final Account account, final Callable<PluginDispatcherReturnType<ReturnType>> callable, PluginDispatcher<ReturnType> pluginFormDispatcher) throws PaymentApiException {
- final UUID accountId = account != null ? account.getId() : null;
- final String accountExternalKey = account != null ? account.getExternalKey() : "";
- try {
- return pluginFormDispatcher.dispatchWithTimeout(callable);
- } catch (final TimeoutException e) {
- throw new PaymentApiException(ErrorCode.PAYMENT_PLUGIN_TIMEOUT, accountId, null);
- } catch (final InterruptedException e) {
- Thread.currentThread().interrupt();
- throw new PaymentApiException(ErrorCode.PAYMENT_INTERNAL_ERROR, Objects.firstNonNull(e.getMessage(), ""));
- } catch (final ExecutionException e) {
- if (e.getCause() instanceof PaymentApiException) {
- throw (PaymentApiException) e.getCause();
- } else if (e.getCause() instanceof LockFailedException) {
- final String format = String.format("Failed to lock account %s", accountExternalKey);
- log.error(String.format(format), e);
- throw new PaymentApiException(ErrorCode.PAYMENT_INTERNAL_ERROR, format);
- } else {
- throw new PaymentApiException(e, ErrorCode.PAYMENT_INTERNAL_ERROR, Objects.firstNonNull(e.getMessage(), ""));
- }
- }
- }
}
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 5dc84f1..2f3e668 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
@@ -24,6 +24,7 @@ import java.util.Collections;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.ExecutorService;
+import java.util.concurrent.TimeUnit;
import javax.annotation.Nullable;
@@ -54,6 +55,7 @@ import org.killbill.billing.tag.TagInternalApi;
import org.killbill.billing.util.cache.CacheControllerDispatcher;
import org.killbill.billing.util.callcontext.CallContext;
import org.killbill.billing.util.callcontext.TenantContext;
+import org.killbill.billing.util.config.PaymentConfig;
import org.killbill.billing.util.dao.NonEntityDao;
import org.killbill.billing.util.entity.Pagination;
import org.killbill.billing.util.entity.dao.DefaultPaginationHelper.EntityPaginationBuilder;
@@ -78,6 +80,8 @@ public class PaymentMethodProcessor extends ProcessorBase {
private static final Logger log = LoggerFactory.getLogger(PaymentMethodProcessor.class);
+ private final PluginDispatcher<UUID> uuidPluginNotificationDispatcher;
+
@Inject
public PaymentMethodProcessor(final OSGIServiceRegistration<PaymentPluginApi> pluginRegistry,
final AccountInternalApi accountInternalApi,
@@ -86,47 +90,49 @@ public class PaymentMethodProcessor extends ProcessorBase {
final NonEntityDao nonEntityDao,
final TagInternalApi tagUserApi,
final GlobalLocker locker,
+ final PaymentConfig paymentConfig,
@Named(PLUGIN_EXECUTOR_NAMED) final ExecutorService executor,
final Clock clock,
final CacheControllerDispatcher controllerDispatcher) {
super(pluginRegistry, accountInternalApi, paymentDao, nonEntityDao, tagUserApi, locker, executor, invoiceApi, clock, controllerDispatcher);
+ final long paymentPluginTimeoutSec = TimeUnit.SECONDS.convert(paymentConfig.getPaymentPluginTimeout().getPeriod(), paymentConfig.getPaymentPluginTimeout().getUnit());
+ this.uuidPluginNotificationDispatcher = new PluginDispatcher<UUID>(paymentPluginTimeoutSec, executor);
}
public UUID addPaymentMethod(final String paymentMethodExternalKey, final String paymentPluginServiceName, final Account account,
final boolean setDefault, final PaymentMethodPlugin paymentMethodProps,
final Iterable<PluginProperty> properties, final CallContext callContext, final InternalCallContext context)
throws PaymentApiException {
- try {
- final PluginDispatcherReturnType<UUID> result = new WithAccountLock<UUID, PaymentApiException>().processAccountWithLock(locker, account.getExternalKey(), new WithAccountLockCallback<PluginDispatcherReturnType<UUID>, PaymentApiException>() {
-
- @Override
- public PluginDispatcherReturnType<UUID> doOperation() throws PaymentApiException {
- PaymentMethod pm = null;
- final PaymentPluginApi pluginApi;
- try {
- pluginApi = getPaymentPluginApi(paymentPluginServiceName);
- pm = new DefaultPaymentMethod(paymentMethodExternalKey, account.getId(), paymentPluginServiceName, paymentMethodProps);
- pluginApi.addPaymentMethod(account.getId(), pm.getId(), paymentMethodProps, setDefault, properties, callContext);
- final PaymentMethodModelDao pmModel = new PaymentMethodModelDao(pm.getId(), pm.getExternalKey(), pm.getCreatedDate(), pm.getUpdatedDate(),
- pm.getAccountId(), pm.getPluginName(), pm.isActive());
- paymentDao.insertPaymentMethod(pmModel, context);
-
- if (setDefault) {
- accountInternalApi.updatePaymentMethod(account.getId(), pm.getId(), context);
- }
- } catch (final PaymentPluginApiException e) {
- log.warn("Error adding payment method " + pm.getId() + " for plugin " + paymentPluginServiceName, e);
- throw new PaymentApiException(ErrorCode.PAYMENT_ADD_PAYMENT_METHOD, account.getId(), e.getErrorMessage());
- } catch (final AccountApiException e) {
- throw new PaymentApiException(e);
- }
- return PluginDispatcher.createPluginDispatcherReturnType(pm.getId());
- }
- });
- return result.getReturnType();
- } catch (final Exception e) {
- throw new PaymentApiException(e, ErrorCode.PAYMENT_INTERNAL_ERROR, Objects.firstNonNull(e.getMessage(), ""));
- }
+ return dispatchWithExceptionHandling(account,
+ new CallableWithAccountLock<UUID, PaymentApiException>(locker,
+ account.getExternalKey(),
+ new WithAccountLockCallback<PluginDispatcherReturnType<UUID>, PaymentApiException>() {
+
+ @Override
+ public PluginDispatcherReturnType<UUID> doOperation() throws PaymentApiException {
+ PaymentMethod pm = null;
+ final PaymentPluginApi pluginApi;
+ try {
+ pluginApi = getPaymentPluginApi(paymentPluginServiceName);
+ pm = new DefaultPaymentMethod(paymentMethodExternalKey, account.getId(), paymentPluginServiceName, paymentMethodProps);
+ pluginApi.addPaymentMethod(account.getId(), pm.getId(), paymentMethodProps, setDefault, properties, callContext);
+ final PaymentMethodModelDao pmModel = new PaymentMethodModelDao(pm.getId(), pm.getExternalKey(), pm.getCreatedDate(), pm.getUpdatedDate(),
+ pm.getAccountId(), pm.getPluginName(), pm.isActive());
+ paymentDao.insertPaymentMethod(pmModel, context);
+
+ if (setDefault) {
+ accountInternalApi.updatePaymentMethod(account.getId(), pm.getId(), context);
+ }
+ } catch (final PaymentPluginApiException e) {
+ log.warn("Error adding payment method " + pm.getId() + " for plugin " + paymentPluginServiceName, e);
+ throw new PaymentApiException(ErrorCode.PAYMENT_ADD_PAYMENT_METHOD, account.getId(), e.getErrorMessage());
+ } catch (final AccountApiException e) {
+ throw new PaymentApiException(e);
+ }
+ return PluginDispatcher.createPluginDispatcherReturnType(pm.getId());
+ }
+ }),
+ uuidPluginNotificationDispatcher);
}
public List<PaymentMethod> getPaymentMethods(final UUID accountId, final boolean withPluginInfo, final Iterable<PluginProperty> properties, final InternalTenantContext context) throws PaymentApiException {
diff --git a/payment/src/main/java/org/killbill/billing/payment/core/ProcessorBase.java b/payment/src/main/java/org/killbill/billing/payment/core/ProcessorBase.java
index 3cc6a94..d9da5e2 100644
--- a/payment/src/main/java/org/killbill/billing/payment/core/ProcessorBase.java
+++ b/payment/src/main/java/org/killbill/billing/payment/core/ProcessorBase.java
@@ -22,7 +22,9 @@ import java.util.List;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
+import java.util.concurrent.TimeoutException;
import javax.annotation.Nullable;
@@ -39,6 +41,7 @@ import org.killbill.billing.payment.api.TransactionStatus;
import org.killbill.billing.payment.dao.PaymentDao;
import org.killbill.billing.payment.dao.PaymentMethodModelDao;
import org.killbill.billing.payment.dao.PaymentTransactionModelDao;
+import org.killbill.billing.payment.dispatcher.PluginDispatcher;
import org.killbill.billing.payment.dispatcher.PluginDispatcher.PluginDispatcherReturnType;
import org.killbill.billing.payment.plugin.api.PaymentPluginApi;
import org.killbill.billing.tag.TagInternalApi;
@@ -58,6 +61,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.base.Function;
+import com.google.common.base.Objects;
import com.google.common.base.Predicate;
import com.google.common.collect.Collections2;
import com.google.common.collect.Iterables;
@@ -220,4 +224,28 @@ public abstract class ProcessorBase {
}
}
}
+
+ protected static <ReturnType> ReturnType dispatchWithExceptionHandling(@Nullable final Account account, final Callable<PluginDispatcherReturnType<ReturnType>> callable, PluginDispatcher<ReturnType> pluginFormDispatcher) throws PaymentApiException {
+ final UUID accountId = account != null ? account.getId() : null;
+ final String accountExternalKey = account != null ? account.getExternalKey() : "";
+ try {
+ return pluginFormDispatcher.dispatchWithTimeout(callable);
+ } catch (final TimeoutException e) {
+ throw new PaymentApiException(ErrorCode.PAYMENT_PLUGIN_TIMEOUT, accountId, null);
+ } catch (final InterruptedException e) {
+ Thread.currentThread().interrupt();
+ throw new PaymentApiException(ErrorCode.PAYMENT_INTERNAL_ERROR, Objects.firstNonNull(e.getMessage(), ""));
+ } catch (final ExecutionException e) {
+ if (e.getCause() instanceof PaymentApiException) {
+ throw (PaymentApiException) e.getCause();
+ } else if (e.getCause() instanceof LockFailedException) {
+ final String format = String.format("Failed to lock account %s", accountExternalKey);
+ log.error(String.format(format), e);
+ throw new PaymentApiException(ErrorCode.PAYMENT_INTERNAL_ERROR, format);
+ } else {
+ throw new PaymentApiException(e, ErrorCode.PAYMENT_INTERNAL_ERROR, Objects.firstNonNull(e.getMessage(), ""));
+ }
+ }
+ }
+
}