killbill-aplcache
Changes
overdue/src/test/java/org/killbill/billing/overdue/glue/ApplicatorMockJunctionModule.java 76(+0 -76)
payment/pom.xml 5(+5 -0)
payment/src/main/java/org/killbill/billing/payment/invoice/InvoicePaymentControlPluginApi.java 58(+51 -7)
Details
diff --git a/overdue/src/main/java/org/killbill/billing/overdue/wrapper/OverdueWrapper.java b/overdue/src/main/java/org/killbill/billing/overdue/wrapper/OverdueWrapper.java
index 0b45601..a7c14f8 100644
--- a/overdue/src/main/java/org/killbill/billing/overdue/wrapper/OverdueWrapper.java
+++ b/overdue/src/main/java/org/killbill/billing/overdue/wrapper/OverdueWrapper.java
@@ -1,7 +1,9 @@
/*
* Copyright 2010-2013 Ning, Inc.
+ * Copyright 2014-2016 Groupon, Inc
+ * Copyright 2014-2016 The Billing Project, LLC
*
- * Ning licenses this file to you under the Apache License, version 2.0
+ * 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:
*
@@ -29,12 +31,24 @@ import org.killbill.billing.overdue.calculator.BillingStateCalculator;
import org.killbill.billing.overdue.config.api.BillingState;
import org.killbill.billing.overdue.config.api.OverdueException;
import org.killbill.billing.overdue.config.api.OverdueStateSet;
+import org.killbill.billing.util.globallocker.LockerType;
import org.killbill.clock.Clock;
+import org.killbill.commons.locker.GlobalLock;
+import org.killbill.commons.locker.GlobalLocker;
+import org.killbill.commons.locker.LockFailedException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
public class OverdueWrapper {
+ private static final Logger log = LoggerFactory.getLogger(OverdueWrapper.class);
+
+ // Should we introduce a config?
+ private static final int MAX_LOCK_RETRIES = 50;
+
private final ImmutableAccountData overdueable;
private final BlockingInternalApi api;
+ private final GlobalLocker locker;
private final Clock clock;
private final OverdueStateSet overdueStateSet;
private final BillingStateCalculator billingStateCalcuator;
@@ -43,12 +57,14 @@ public class OverdueWrapper {
public OverdueWrapper(final ImmutableAccountData overdueable,
final BlockingInternalApi api,
final OverdueStateSet overdueStateSet,
+ final GlobalLocker locker,
final Clock clock,
final BillingStateCalculator billingStateCalcuator,
final OverdueStateApplicator overdueStateApplicator) {
this.overdueable = overdueable;
this.overdueStateSet = overdueStateSet;
this.api = api;
+ this.locker = locker;
this.clock = clock;
this.billingStateCalcuator = billingStateCalcuator;
this.overdueStateApplicator = overdueStateApplicator;
@@ -59,6 +75,23 @@ public class OverdueWrapper {
return overdueStateSet.getClearState();
}
+ GlobalLock lock = null;
+ try {
+ lock = locker.lockWithNumberOfTries(LockerType.ACCNT_INV_PAY.toString(), overdueable.getId().toString(), MAX_LOCK_RETRIES);
+
+ return refreshWithLock(context);
+ } catch (final LockFailedException e) {
+ // Not good!
+ log.error(String.format("Failed to process overdue for account %s", overdueable.getId()), e);
+ } finally {
+ if (lock != null) {
+ lock.release();
+ }
+ }
+ return null;
+ }
+
+ private OverdueState refreshWithLock(final InternalCallContext context) throws OverdueException, OverdueApiException {
final BillingState billingState = billingState(context);
final String previousOverdueStateName = api.getBlockingStateForService(overdueable.getId(), BlockingStateType.ACCOUNT, OverdueService.OVERDUE_SERVICE_NAME, context).getStateName();
@@ -71,6 +104,22 @@ public class OverdueWrapper {
}
public void clear(final InternalCallContext context) throws OverdueException, OverdueApiException {
+ GlobalLock lock = null;
+ try {
+ lock = locker.lockWithNumberOfTries(LockerType.ACCNT_INV_PAY.toString(), overdueable.getId().toString(), MAX_LOCK_RETRIES);
+
+ clearWithLock(context);
+ } catch (final LockFailedException e) {
+ // Not good!
+ log.error(String.format("Failed to clear overdue for account %s", overdueable.getId()), e);
+ } finally {
+ if (lock != null) {
+ lock.release();
+ }
+ }
+ }
+
+ private void clearWithLock(final InternalCallContext context) throws OverdueException, OverdueApiException {
final String previousOverdueStateName = api.getBlockingStateForService(overdueable.getId(), BlockingStateType.ACCOUNT, OverdueService.OVERDUE_SERVICE_NAME, context).getStateName();
final OverdueState previousOverdueState = overdueStateSet.findState(previousOverdueStateName);
overdueStateApplicator.clear(overdueable, previousOverdueState, overdueStateSet.getClearState(), context);
diff --git a/overdue/src/main/java/org/killbill/billing/overdue/wrapper/OverdueWrapperFactory.java b/overdue/src/main/java/org/killbill/billing/overdue/wrapper/OverdueWrapperFactory.java
index 9c51f85..bec4c53 100644
--- a/overdue/src/main/java/org/killbill/billing/overdue/wrapper/OverdueWrapperFactory.java
+++ b/overdue/src/main/java/org/killbill/billing/overdue/wrapper/OverdueWrapperFactory.java
@@ -1,7 +1,9 @@
/*
* Copyright 2010-2013 Ning, Inc.
+ * Copyright 2014-2016 Groupon, Inc
+ * Copyright 2014-2016 The Billing Project, LLC
*
- * Ning licenses this file to you under the Apache License, version 2.0
+ * 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:
*
@@ -35,6 +37,7 @@ import org.killbill.billing.overdue.config.DefaultOverdueStateSet;
import org.killbill.billing.overdue.config.api.OverdueException;
import org.killbill.billing.overdue.config.api.OverdueStateSet;
import org.killbill.clock.Clock;
+import org.killbill.commons.locker.GlobalLocker;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -48,11 +51,14 @@ public class OverdueWrapperFactory {
private final BillingStateCalculator billingStateCalculator;
private final OverdueStateApplicator overdueStateApplicator;
private final BlockingInternalApi api;
+ private final GlobalLocker locker;
private final Clock clock;
private final OverdueConfigCache overdueConfigCache;
@Inject
- public OverdueWrapperFactory(final BlockingInternalApi api, final Clock clock,
+ public OverdueWrapperFactory(final BlockingInternalApi api,
+ final GlobalLocker locker,
+ final Clock clock,
final BillingStateCalculator billingStateCalculator,
final OverdueStateApplicator overdueStateApplicatorBundle,
final OverdueConfigCache overdueConfigCache,
@@ -61,24 +67,20 @@ public class OverdueWrapperFactory {
this.overdueStateApplicator = overdueStateApplicatorBundle;
this.accountApi = accountApi;
this.api = api;
+ this.locker = locker;
this.clock = clock;
this.overdueConfigCache = overdueConfigCache;
}
- @SuppressWarnings("unchecked")
public OverdueWrapper createOverdueWrapperFor(final ImmutableAccountData blockable, final InternalTenantContext context) throws OverdueException {
- return (OverdueWrapper) new OverdueWrapper(blockable, api, getOverdueStateSet(context),
- clock, billingStateCalculator, overdueStateApplicator);
+ return new OverdueWrapper(blockable, api, getOverdueStateSet(context), locker, clock, billingStateCalculator, overdueStateApplicator);
}
- @SuppressWarnings("unchecked")
public OverdueWrapper createOverdueWrapperFor(final UUID id, final InternalTenantContext context) throws OverdueException {
-
try {
final ImmutableAccountData account = accountApi.getImmutableAccountDataById(id, context);
- return new OverdueWrapper(account, api, getOverdueStateSet(context),
- clock, billingStateCalculator, overdueStateApplicator);
- } catch (AccountApiException e) {
+ return new OverdueWrapper(account, api, getOverdueStateSet(context), locker, clock, billingStateCalculator, overdueStateApplicator);
+ } catch (final AccountApiException e) {
throw new OverdueException(e);
}
}
@@ -104,7 +106,7 @@ public class OverdueWrapperFactory {
} else {
return ((DefaultOverdueConfig) overdueConfig).getOverdueStatesAccount();
}
- } catch (OverdueApiException e) {
+ } catch (final OverdueApiException e) {
throw new OverdueException(e);
}
}
diff --git a/overdue/src/test/java/org/killbill/billing/overdue/glue/TestOverdueModule.java b/overdue/src/test/java/org/killbill/billing/overdue/glue/TestOverdueModule.java
index d858aa1..142f39d 100644
--- a/overdue/src/test/java/org/killbill/billing/overdue/glue/TestOverdueModule.java
+++ b/overdue/src/test/java/org/killbill/billing/overdue/glue/TestOverdueModule.java
@@ -1,7 +1,7 @@
/*
* Copyright 2010-2013 Ning, Inc.
- * Copyright 2014 Groupon, Inc
- * Copyright 2014 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
@@ -18,6 +18,15 @@
package org.killbill.billing.overdue.glue;
+import java.util.List;
+import java.util.UUID;
+
+import org.killbill.billing.callcontext.InternalCallContext;
+import org.killbill.billing.callcontext.InternalTenantContext;
+import org.killbill.billing.entitlement.api.BlockingState;
+import org.killbill.billing.entitlement.api.BlockingStateType;
+import org.killbill.billing.junction.BlockingInternalApi;
+import org.killbill.billing.junction.DefaultBlockingState;
import org.killbill.billing.mock.glue.MockAccountModule;
import org.killbill.billing.mock.glue.MockEntitlementModule;
import org.killbill.billing.mock.glue.MockInvoiceModule;
@@ -25,7 +34,6 @@ import org.killbill.billing.mock.glue.MockTagModule;
import org.killbill.billing.mock.glue.MockTenantModule;
import org.killbill.billing.overdue.TestOverdueHelper;
import org.killbill.billing.overdue.applicator.OverdueBusListenerTester;
-import org.killbill.billing.overdue.caching.EhCacheOverdueConfigCache;
import org.killbill.billing.overdue.caching.MockOverdueConfigCache;
import org.killbill.billing.overdue.caching.OverdueCacheInvalidationCallback;
import org.killbill.billing.overdue.caching.OverdueConfigCache;
@@ -37,6 +45,8 @@ import org.killbill.billing.util.glue.AuditModule;
import org.killbill.billing.util.glue.CacheModule;
import org.killbill.billing.util.glue.CallContextModule;
import org.killbill.billing.util.glue.CustomFieldModule;
+import org.killbill.billing.util.glue.MemoryGlobalLockerModule;
+import org.killbill.clock.ClockMock;
import com.google.inject.name.Names;
@@ -56,15 +66,12 @@ public class TestOverdueModule extends DefaultOverdueModule {
install(new CustomFieldModule(configSource));
install(new EmailModule(configSource));
install(new MockAccountModule(configSource));
- install(new MockEntitlementModule(configSource));
+ install(new MockEntitlementModule(configSource, new ApplicatorBlockingApi()));
install(new MockInvoiceModule(configSource));
install(new MockTagModule(configSource));
install(new TemplateModule(configSource));
install(new MockTenantModule(configSource));
-
-
- // We can't use the dumb mocks in MockJunctionModule here
- install(new ApplicatorMockJunctionModule(configSource));
+ install(new MemoryGlobalLockerModule(configSource));
bind(OverdueBusListenerTester.class).asEagerSingleton();
bind(TestOverdueHelper.class).asEagerSingleton();
@@ -75,4 +82,31 @@ public class TestOverdueModule extends DefaultOverdueModule {
bind(CacheInvalidationCallback.class).annotatedWith(Names.named(OVERDUE_INVALIDATION_CALLBACK)).to(OverdueCacheInvalidationCallback.class).asEagerSingleton();
}
+ public static class ApplicatorBlockingApi implements BlockingInternalApi {
+
+ private BlockingState blockingState;
+
+ public BlockingState getBlockingState() {
+ return blockingState;
+ }
+
+ @Override
+ public BlockingState getBlockingStateForService(final UUID blockableId, final BlockingStateType blockingStateType, final String serviceName, final InternalTenantContext context) {
+ if (blockingState != null && blockingState.getBlockedId().equals(blockableId)) {
+ return blockingState;
+ } else {
+ return DefaultBlockingState.getClearState(blockingStateType, serviceName, new ClockMock());
+ }
+ }
+
+ @Override
+ public List<BlockingState> getBlockingAllForAccount(final InternalTenantContext context) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void setBlockingState(final BlockingState state, final InternalCallContext context) {
+ blockingState = state;
+ }
+ }
}
diff --git a/overdue/src/test/java/org/killbill/billing/overdue/TestOverdueHelper.java b/overdue/src/test/java/org/killbill/billing/overdue/TestOverdueHelper.java
index 0e74a22..3f09ee6 100644
--- a/overdue/src/test/java/org/killbill/billing/overdue/TestOverdueHelper.java
+++ b/overdue/src/test/java/org/killbill/billing/overdue/TestOverdueHelper.java
@@ -1,7 +1,9 @@
/*
* Copyright 2010-2013 Ning, Inc.
+ * Copyright 2014-2016 Groupon, Inc
+ * Copyright 2014-2016 The Billing Project, LLC
*
- * Ning licenses this file to you under the Apache License, version 2.0
+ * 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:
*
@@ -25,6 +27,7 @@ import org.joda.time.DateTimeZone;
import org.joda.time.LocalDate;
import org.killbill.billing.account.api.ImmutableAccountData;
import org.killbill.billing.overdue.api.OverdueState;
+import org.killbill.billing.overdue.glue.TestOverdueModule.ApplicatorBlockingApi;
import org.mockito.Mockito;
import org.testng.Assert;
@@ -32,7 +35,6 @@ import org.killbill.billing.account.api.AccountApiException;
import org.killbill.billing.invoice.api.Invoice;
import org.killbill.billing.invoice.api.InvoiceItem;
import org.killbill.billing.entitlement.api.BlockingState;
-import org.killbill.billing.overdue.glue.ApplicatorMockJunctionModule.ApplicatorBlockingApi;
import org.killbill.billing.subscription.api.user.SubscriptionBaseApiException;
import org.killbill.billing.callcontext.InternalTenantContext;
import org.killbill.billing.account.api.AccountInternalApi;
payment/pom.xml 5(+5 -0)
diff --git a/payment/pom.xml b/payment/pom.xml
index 97119a8..c8e9e55 100644
--- a/payment/pom.xml
+++ b/payment/pom.xml
@@ -105,6 +105,11 @@
</dependency>
<dependency>
<groupId>org.kill-bill.billing</groupId>
+ <artifactId>killbill-overdue</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.kill-bill.billing</groupId>
<artifactId>killbill-platform-api</artifactId>
</dependency>
<dependency>
diff --git a/payment/src/main/java/org/killbill/billing/payment/invoice/InvoicePaymentControlPluginApi.java b/payment/src/main/java/org/killbill/billing/payment/invoice/InvoicePaymentControlPluginApi.java
index 69614d8..1a771c4 100644
--- a/payment/src/main/java/org/killbill/billing/payment/invoice/InvoicePaymentControlPluginApi.java
+++ b/payment/src/main/java/org/killbill/billing/payment/invoice/InvoicePaymentControlPluginApi.java
@@ -31,6 +31,9 @@ import javax.inject.Named;
import org.joda.time.DateTime;
import org.killbill.billing.ErrorCode;
import org.killbill.billing.ObjectType;
+import org.killbill.billing.account.api.Account;
+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.OnFailurePaymentControlResult;
@@ -45,6 +48,9 @@ import org.killbill.billing.invoice.api.InvoiceApiException;
import org.killbill.billing.invoice.api.InvoiceInternalApi;
import org.killbill.billing.invoice.api.InvoiceItem;
import org.killbill.billing.invoice.api.InvoicePayment;
+import org.killbill.billing.overdue.OverdueInternalApi;
+import org.killbill.billing.overdue.api.OverdueApiException;
+import org.killbill.billing.overdue.config.api.OverdueException;
import org.killbill.billing.payment.api.PaymentApiException;
import org.killbill.billing.payment.api.PluginProperty;
import org.killbill.billing.payment.api.TransactionStatus;
@@ -89,7 +95,9 @@ public final class InvoicePaymentControlPluginApi implements PaymentControlPlugi
public static final String PROP_IPCD_REFUND_WITH_ADJUSTMENTS = "IPCD_REFUND_WITH_ADJUSTMENTS";
private final PaymentConfig paymentConfig;
+ private final AccountInternalApi accountApi;
private final InvoiceInternalApi invoiceApi;
+ private final OverdueInternalApi overdueApi;
private final TagUserApi tagApi;
private final PaymentDao paymentDao;
private final InvoicePaymentControlDao controlDao;
@@ -100,12 +108,15 @@ public final class InvoicePaymentControlPluginApi implements PaymentControlPlugi
private final Logger log = LoggerFactory.getLogger(InvoicePaymentControlPluginApi.class);
@Inject
- public InvoicePaymentControlPluginApi(final PaymentConfig paymentConfig, final InvoiceInternalApi invoiceApi, final TagUserApi tagApi, final PaymentDao paymentDao,
- final InvoicePaymentControlDao invoicePaymentControlDao,
+ public InvoicePaymentControlPluginApi(final PaymentConfig paymentConfig, final AccountInternalApi accountApi,
+ final InvoiceInternalApi invoiceApi, final OverdueInternalApi overdueApi, final TagUserApi tagApi,
+ final PaymentDao paymentDao, final InvoicePaymentControlDao invoicePaymentControlDao,
@Named(PaymentModule.RETRYABLE_NAMED) final RetryServiceScheduler retryServiceScheduler,
final InternalCallContextFactory internalCallContextFactory, final Clock clock) {
this.paymentConfig = paymentConfig;
+ this.accountApi = accountApi;
this.invoiceApi = invoiceApi;
+ this.overdueApi = overdueApi;
this.tagApi = tagApi;
this.paymentDao = paymentDao;
this.controlDao = invoicePaymentControlDao;
@@ -143,6 +154,7 @@ public final class InvoicePaymentControlPluginApi implements PaymentControlPlugi
transactionType == TransactionType.REFUND ||
transactionType == TransactionType.CHARGEBACK);
+ boolean refreshOverdue = false;
final InternalCallContext internalContext = internalCallContextFactory.createInternalCallContext(paymentControlContext.getAccountId(), paymentControlContext);
try {
final InvoicePayment existingInvoicePayment;
@@ -162,6 +174,7 @@ public final class InvoicePaymentControlPluginApi implements PaymentControlPlugi
paymentControlContext.getCreatedDate(),
true,
internalContext);
+ refreshOverdue = true;
}
break;
@@ -174,6 +187,7 @@ public final class InvoicePaymentControlPluginApi implements PaymentControlPlugi
final PluginProperty prop = getPluginProperty(pluginProperties, PROP_IPCD_REFUND_WITH_ADJUSTMENTS);
final boolean isAdjusted = prop != null ? Boolean.valueOf((String) prop.getValue()) : false;
invoiceApi.createRefund(paymentControlContext.getPaymentId(), paymentControlContext.getAmount(), isAdjusted, idWithAmount, paymentControlContext.getTransactionExternalKey(), internalContext);
+ refreshOverdue = true;
}
break;
@@ -183,6 +197,7 @@ public final class InvoicePaymentControlPluginApi implements PaymentControlPlugi
log.info("onSuccessCall was already completed for payment chargeback: " + paymentControlContext.getPaymentId());
} else {
invoiceApi.createChargeback(paymentControlContext.getPaymentId(), paymentControlContext.getProcessedAmount(), paymentControlContext.getProcessedCurrency(), internalContext);
+ refreshOverdue = true;
}
break;
@@ -192,6 +207,11 @@ public final class InvoicePaymentControlPluginApi implements PaymentControlPlugi
} catch (final InvoiceApiException e) {
log.error("InvoicePaymentControlPluginApi onSuccessCall failed for attemptId = " + paymentControlContext.getAttemptPaymentId() + ", transactionType = " + transactionType, e);
}
+
+ if (refreshOverdue) {
+ refreshOverdue(paymentControlContext, internalContext);
+ }
+
return new DefaultOnSuccessPaymentControlResult();
}
@@ -199,6 +219,9 @@ public final class InvoicePaymentControlPluginApi implements PaymentControlPlugi
public OnFailurePaymentControlResult onFailureCall(final PaymentControlContext paymentControlContext, final Iterable<PluginProperty> pluginProperties) throws PaymentControlApiException {
final InternalCallContext internalContext = internalCallContextFactory.createInternalCallContext(paymentControlContext.getAccountId(), paymentControlContext);
final TransactionType transactionType = paymentControlContext.getTransactionType();
+
+ boolean refreshOverdue = false;
+ DateTime nextRetryDate = null;
switch (transactionType) {
case PURCHASE:
final UUID invoiceId = getInvoiceId(pluginProperties);
@@ -214,20 +237,27 @@ public final class InvoicePaymentControlPluginApi implements PaymentControlPlugi
paymentControlContext.getCreatedDate(),
false,
internalContext);
- } catch (InvoiceApiException e) {
+ refreshOverdue = true;
+ } catch (final InvoiceApiException e) {
log.error("InvoicePaymentControlPluginApi onFailureCall failed ton update invoice for attemptId = " + paymentControlContext.getAttemptPaymentId() + ", transactionType = " + transactionType, e);
}
}
- final DateTime nextRetryDate = computeNextRetryDate(paymentControlContext.getPaymentExternalKey(), paymentControlContext.isApiPayment(), internalContext);
- return new DefaultFailureCallResult(nextRetryDate);
+ nextRetryDate = computeNextRetryDate(paymentControlContext.getPaymentExternalKey(), paymentControlContext.isApiPayment(), internalContext);
+ break;
case REFUND:
case CHARGEBACK:
- // We don't retry REFUND, CHARGEBACK
- return new DefaultFailureCallResult(null);
+ // We don't retry REFUND, CHARGEBACK
+ break;
default:
throw new IllegalStateException("Unexpected transactionType " + transactionType);
}
+
+ if (refreshOverdue) {
+ refreshOverdue(paymentControlContext, internalContext);
+ }
+
+ return new DefaultFailureCallResult(nextRetryDate);
}
public void process_AUTO_PAY_OFF_removal(final UUID accountId, final InternalCallContext internalCallContext) {
@@ -516,4 +546,18 @@ public final class InvoicePaymentControlPluginApi implements PaymentControlPlugi
}
}));
}
+
+ // See https://github.com/killbill/killbill/issues/472
+ private void refreshOverdue(final PaymentControlContext paymentControlContext, final InternalCallContext internalContext) {
+ try {
+ final Account account = accountApi.getAccountById(paymentControlContext.getAccountId(), internalContext);
+ overdueApi.refreshOverdueStateFor(account, internalContext.toCallContext(paymentControlContext.getTenantId()));
+ } catch (final AccountApiException e) {
+ log.warn("Unable to refresh overdue for accountId={}: {}", paymentControlContext.getAccountId(), e);
+ } catch (final OverdueApiException e) {
+ log.warn("Unable to refresh overdue for accountId={}: {}", paymentControlContext.getAccountId(), e);
+ } catch (final OverdueException e) {
+ log.warn("Unable to refresh overdue for accountId={}: {}", paymentControlContext.getAccountId(), e);
+ }
+ }
}
diff --git a/payment/src/test/java/org/killbill/billing/payment/glue/MockEntitlementModuleForPayment.java b/payment/src/test/java/org/killbill/billing/payment/glue/MockEntitlementModuleForPayment.java
new file mode 100644
index 0000000..f98b0cf
--- /dev/null
+++ b/payment/src/test/java/org/killbill/billing/payment/glue/MockEntitlementModuleForPayment.java
@@ -0,0 +1,50 @@
+/*
+ * 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
+ * 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.glue;
+
+import java.util.UUID;
+
+import org.joda.time.DateTime;
+import org.joda.time.DateTimeZone;
+import org.killbill.billing.callcontext.InternalTenantContext;
+import org.killbill.billing.entitlement.api.BlockingState;
+import org.killbill.billing.entitlement.api.BlockingStateType;
+import org.killbill.billing.junction.BlockingInternalApi;
+import org.killbill.billing.junction.DefaultBlockingState;
+import org.killbill.billing.mock.glue.MockEntitlementModule;
+import org.killbill.billing.platform.api.KillbillConfigSource;
+import org.mockito.Mockito;
+
+import com.google.common.collect.ImmutableList;
+import com.google.inject.Module;
+
+public class MockEntitlementModuleForPayment extends MockEntitlementModule {
+
+ public MockEntitlementModuleForPayment(final KillbillConfigSource configSource) {
+ super(configSource);
+ }
+
+ @Override
+ public void installBlockingApi() {
+ super.installBlockingApi();
+
+ final BlockingState blockingState = new DefaultBlockingState(null, BlockingStateType.ACCOUNT, "clear", "test", false, false, false, new DateTime(DateTimeZone.UTC));
+ Mockito.when(blockingApi.getBlockingAllForAccount(Mockito.<InternalTenantContext>any())).thenReturn(ImmutableList.<BlockingState>of(blockingState));
+ Mockito.when(blockingApi.getBlockingStateForService(Mockito.<UUID>any(), Mockito.<BlockingStateType>any(), Mockito.anyString(), Mockito.<InternalTenantContext>any())).thenReturn(blockingState);
+ }
+}
diff --git a/payment/src/test/java/org/killbill/billing/payment/glue/TestPaymentModule.java b/payment/src/test/java/org/killbill/billing/payment/glue/TestPaymentModule.java
index 2b1ca1f..020de2b 100644
--- a/payment/src/test/java/org/killbill/billing/payment/glue/TestPaymentModule.java
+++ b/payment/src/test/java/org/killbill/billing/payment/glue/TestPaymentModule.java
@@ -1,7 +1,7 @@
/*
* Copyright 2010-2013 Ning, Inc.
- * 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
@@ -25,6 +25,7 @@ import org.killbill.billing.callcontext.InternalTenantContext;
import org.killbill.billing.mock.glue.MockInvoiceModule;
import org.killbill.billing.mock.glue.MockSubscriptionModule;
import org.killbill.billing.mock.glue.MockTenantModule;
+import org.killbill.billing.overdue.glue.DefaultOverdueModule;
import org.killbill.billing.payment.TestPaymentHelper;
import org.killbill.billing.payment.provider.MockPaymentProviderPlugin;
import org.killbill.billing.payment.provider.MockPaymentProviderPluginModule;
@@ -32,6 +33,8 @@ import org.killbill.billing.platform.api.KillbillConfigSource;
import org.killbill.billing.tag.TagInternalApi;
import org.killbill.billing.util.api.TagUserApi;
import org.killbill.billing.util.config.PaymentConfig;
+import org.killbill.billing.util.email.EmailModule;
+import org.killbill.billing.util.email.templates.TemplateModule;
import org.killbill.billing.util.glue.CacheModule;
import org.killbill.billing.util.glue.CallContextModule;
import org.killbill.billing.util.glue.MemoryGlobalLockerModule;
@@ -73,6 +76,12 @@ public class TestPaymentModule extends PaymentModule {
install(new MockTenantModule(configSource));
install(new CacheModule(configSource));
install(new CallContextModule(configSource));
+
+ install(new DefaultOverdueModule(configSource));
+ install(new TemplateModule(configSource));
+ install(new EmailModule(configSource));
+ install(new MockEntitlementModuleForPayment(configSource));
+
installExternalApis();
bind(TestPaymentHelper.class).asEagerSingleton();
}
diff --git a/util/src/test/java/org/killbill/billing/mock/glue/MockEntitlementModule.java b/util/src/test/java/org/killbill/billing/mock/glue/MockEntitlementModule.java
index 79fd448..eb68eac 100644
--- a/util/src/test/java/org/killbill/billing/mock/glue/MockEntitlementModule.java
+++ b/util/src/test/java/org/killbill/billing/mock/glue/MockEntitlementModule.java
@@ -1,7 +1,7 @@
/*
* Copyright 2010-2013 Ning, Inc.
- * Copyright 2014 Groupon, Inc
- * Copyright 2014 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
@@ -29,13 +29,19 @@ import org.mockito.Mockito;
public class MockEntitlementModule extends KillBillModule implements EntitlementModule {
- private final BlockingInternalApi blockingApi = Mockito.mock(BlockingInternalApi.class);
private final EntitlementApi entitlementApi = Mockito.mock(EntitlementApi.class);
private final EntitlementInternalApi entitlementInternalApi = Mockito.mock(EntitlementInternalApi.class);
private final SubscriptionApi subscriptionApi = Mockito.mock(SubscriptionApi.class);
+ protected final BlockingInternalApi blockingApi;
+
public MockEntitlementModule(final KillbillConfigSource configSource) {
+ this(configSource, Mockito.mock(BlockingInternalApi.class));
+ }
+
+ public MockEntitlementModule(final KillbillConfigSource configSource, final BlockingInternalApi blockingApi) {
super(configSource);
+ this.blockingApi = blockingApi;
}
@Override
@@ -53,7 +59,7 @@ public class MockEntitlementModule extends KillBillModule implements Entitlement
@Override
public void installBlockingApi() {
- //bind(BlockingInternalApi.class).toInstance(blockingApi);
+ bind(BlockingInternalApi.class).toInstance(blockingApi);
}
@Override