Details
diff --git a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestIntegrationBase.java b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestIntegrationBase.java
index ab221ba..5136b19 100644
--- a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestIntegrationBase.java
+++ b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestIntegrationBase.java
@@ -74,7 +74,7 @@ import org.killbill.billing.lifecycle.api.Lifecycle;
import org.killbill.billing.lifecycle.glue.BusModule;
import org.killbill.billing.mock.MockAccountBuilder;
import org.killbill.billing.osgi.config.OSGIConfig;
-import org.killbill.billing.overdue.OverdueInternalApi;
+import org.killbill.billing.overdue.api.OverdueApi;
import org.killbill.billing.overdue.api.OverdueConfig;
import org.killbill.billing.overdue.caching.OverdueConfigCache;
import org.killbill.billing.overdue.listener.OverdueListener;
@@ -177,7 +177,7 @@ public class TestIntegrationBase extends BeatrixTestSuiteWithEmbeddedDB {
protected SubscriptionBaseTimelineApi repairApi;
@Inject
- protected OverdueInternalApi overdueUserApi;
+ protected OverdueApi overdueUserApi;
@Inject
protected InvoiceUserApi invoiceUserApi;
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/AccountResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/AccountResource.java
index 78e0552..692900c 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/AccountResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/AccountResource.java
@@ -82,7 +82,7 @@ import org.killbill.billing.jaxrs.json.PaymentTransactionJson;
import org.killbill.billing.jaxrs.json.TagJson;
import org.killbill.billing.jaxrs.util.Context;
import org.killbill.billing.jaxrs.util.JaxrsUriBuilder;
-import org.killbill.billing.overdue.OverdueInternalApi;
+import org.killbill.billing.overdue.api.OverdueApi;
import org.killbill.billing.overdue.api.OverdueApiException;
import org.killbill.billing.overdue.api.OverdueState;
import org.killbill.billing.overdue.config.api.OverdueException;
@@ -138,7 +138,7 @@ public class AccountResource extends JaxRsResourceBase {
private final SubscriptionApi subscriptionApi;
private final InvoiceUserApi invoiceApi;
private final InvoicePaymentApi invoicePaymentApi;
- private final OverdueInternalApi overdueApi;
+ private final OverdueApi overdueApi;
private final PaymentConfig paymentConfig;
private final JaxrsExecutors jaxrsExecutors;
private final JaxrsConfig jaxrsConfig;
@@ -153,7 +153,7 @@ public class AccountResource extends JaxRsResourceBase {
final AuditUserApi auditUserApi,
final CustomFieldUserApi customFieldUserApi,
final SubscriptionApi subscriptionApi,
- final OverdueInternalApi overdueApi,
+ final OverdueApi overdueApi,
final Clock clock,
final PaymentConfig paymentConfig,
final JaxrsExecutors jaxrsExecutors,
@@ -368,7 +368,6 @@ public class AccountResource extends JaxRsResourceBase {
return Response.status(Status.INTERNAL_SERVER_ERROR).build();
}
-
@TimedResource
@GET
@Path("/{accountId:" + UUID_PATTERN + "}/" + TIMELINE)
@@ -792,7 +791,6 @@ public class AccountResource extends JaxRsResourceBase {
return Response.status(Status.OK).build();
}
-
@TimedResource
@PUT
@Consumes(APPLICATION_JSON)
@@ -964,7 +962,7 @@ public class AccountResource extends JaxRsResourceBase {
final TenantContext tenantContext = context.createContext(request);
final Account account = accountUserApi.getAccountById(UUID.fromString(accountId), tenantContext);
- final OverdueState overdueState = overdueApi.getOverdueStateFor(account, tenantContext);
+ final OverdueState overdueState = overdueApi.getOverdueStateFor(account.getId(), tenantContext);
return Response.status(Status.OK).entity(new OverdueStateJson(overdueState, paymentConfig)).build();
}
@@ -1059,7 +1057,6 @@ public class AccountResource extends JaxRsResourceBase {
return createTagResponse(accountId, tags, auditMode, tenantContext);
}
-
@TimedResource
@POST
@Path("/{accountId:" + UUID_PATTERN + "}/" + TAGS)
@@ -1169,7 +1166,7 @@ public class AccountResource extends JaxRsResourceBase {
}
}
)
- .orNull();
+ .orNull();
if (existingEmail == null) {
accountUserApi.addEmail(accountId, json.toAccountEmail(UUIDs.randomUUID()), callContext);
}
diff --git a/overdue/src/main/java/org/killbill/billing/overdue/api/DefaultOverdueApi.java b/overdue/src/main/java/org/killbill/billing/overdue/api/DefaultOverdueApi.java
index 8540b0e..580e4f9 100644
--- a/overdue/src/main/java/org/killbill/billing/overdue/api/DefaultOverdueApi.java
+++ b/overdue/src/main/java/org/killbill/billing/overdue/api/DefaultOverdueApi.java
@@ -17,10 +17,19 @@
package org.killbill.billing.overdue.api;
+import java.util.UUID;
+
import javax.inject.Inject;
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.overdue.OverdueService;
import org.killbill.billing.overdue.caching.OverdueConfigCache;
+import org.killbill.billing.overdue.config.DefaultOverdueConfig;
+import org.killbill.billing.overdue.config.api.OverdueStateSet;
+import org.killbill.billing.overdue.wrapper.OverdueWrapper;
import org.killbill.billing.tenant.api.TenantApiException;
import org.killbill.billing.tenant.api.TenantKV.TenantKey;
import org.killbill.billing.tenant.api.TenantUserApi;
@@ -31,15 +40,18 @@ import org.killbill.billing.util.callcontext.TenantContext;
public class DefaultOverdueApi implements OverdueApi {
private final OverdueConfigCache overdueConfigCache;
+ private final BlockingInternalApi blockingInternalApi;
private final InternalCallContextFactory internalCallContextFactory;
private final TenantUserApi tenantApi;
@Inject
public DefaultOverdueApi(final OverdueConfigCache overdueConfigCache,
final TenantUserApi tenantApi,
+ final BlockingInternalApi blockingInternalApi,
final InternalCallContextFactory internalCallContextFactory) {
this.overdueConfigCache = overdueConfigCache;
this.tenantApi = tenantApi;
+ this.blockingInternalApi = blockingInternalApi;
this.internalCallContextFactory = internalCallContextFactory;
}
@@ -64,6 +76,16 @@ public class DefaultOverdueApi implements OverdueApi {
}
}
+ @Override
+ public OverdueState getOverdueStateFor(final UUID accountId, final TenantContext tenantContext) throws OverdueApiException {
+ final InternalTenantContext internalTenantContext = internalCallContextFactory.createInternalTenantContext(accountId, tenantContext);
+ final BlockingState blockingStateForService = blockingInternalApi.getBlockingStateForService(accountId, BlockingStateType.ACCOUNT, OverdueService.OVERDUE_SERVICE_NAME, internalTenantContext);
+ final String stateName = blockingStateForService != null ? blockingStateForService.getStateName() : OverdueWrapper.CLEAR_STATE_NAME;
+ final OverdueConfig overdueConfig = overdueConfigCache.getOverdueConfig(internalTenantContext);
+ final OverdueStateSet states = ((DefaultOverdueConfig) overdueConfig).getOverdueStatesAccount();
+ return states.findState(stateName);
+ }
+
private InternalTenantContext createInternalTenantContext(final TenantContext tenantContext) {
// Only tenantRecordId will be populated -- this is important to always create the (ehcache) key the same way
return internalCallContextFactory.createInternalTenantContextWithoutAccountRecordId(tenantContext);
diff --git a/overdue/src/main/java/org/killbill/billing/overdue/glue/DefaultOverdueModule.java b/overdue/src/main/java/org/killbill/billing/overdue/glue/DefaultOverdueModule.java
index 9c613e5..930c774 100644
--- a/overdue/src/main/java/org/killbill/billing/overdue/glue/DefaultOverdueModule.java
+++ b/overdue/src/main/java/org/killbill/billing/overdue/glue/DefaultOverdueModule.java
@@ -19,11 +19,9 @@
package org.killbill.billing.overdue.glue;
import org.killbill.billing.glue.OverdueModule;
-import org.killbill.billing.overdue.OverdueInternalApi;
import org.killbill.billing.overdue.OverdueProperties;
import org.killbill.billing.overdue.OverdueService;
import org.killbill.billing.overdue.api.DefaultOverdueApi;
-import org.killbill.billing.overdue.api.DefaultOverdueInternalApi;
import org.killbill.billing.overdue.api.OverdueApi;
import org.killbill.billing.overdue.applicator.OverdueEmailGenerator;
import org.killbill.billing.overdue.applicator.formatters.DefaultOverdueEmailFormatterFactory;
@@ -95,7 +93,6 @@ public class DefaultOverdueModule extends KillBillModule implements OverdueModul
@Override
public void installOverdueUserApi() {
- bind(OverdueInternalApi.class).to(DefaultOverdueInternalApi.class).asEagerSingleton();
bind(OverdueApi.class).to(DefaultOverdueApi.class).asEagerSingleton();
}
diff --git a/overdue/src/main/java/org/killbill/billing/overdue/listener/OverdueListener.java b/overdue/src/main/java/org/killbill/billing/overdue/listener/OverdueListener.java
index 47b4071..867b81f 100644
--- a/overdue/src/main/java/org/killbill/billing/overdue/listener/OverdueListener.java
+++ b/overdue/src/main/java/org/killbill/billing/overdue/listener/OverdueListener.java
@@ -20,14 +20,26 @@ package org.killbill.billing.overdue.listener;
import java.util.UUID;
+import javax.inject.Named;
+
import org.killbill.billing.ObjectType;
import org.killbill.billing.callcontext.InternalCallContext;
+import org.killbill.billing.callcontext.InternalTenantContext;
import org.killbill.billing.events.ControlTagCreationInternalEvent;
import org.killbill.billing.events.ControlTagDeletionInternalEvent;
import org.killbill.billing.events.InvoiceAdjustmentInternalEvent;
import org.killbill.billing.events.InvoicePaymentErrorInternalEvent;
import org.killbill.billing.events.InvoicePaymentInfoInternalEvent;
-import org.killbill.billing.overdue.OverdueInternalApi;
+import org.killbill.billing.overdue.api.OverdueApiException;
+import org.killbill.billing.overdue.api.OverdueConfig;
+import org.killbill.billing.overdue.caching.OverdueConfigCache;
+import org.killbill.billing.overdue.config.DefaultOverdueConfig;
+import org.killbill.billing.overdue.config.DefaultOverdueState;
+import org.killbill.billing.overdue.glue.DefaultOverdueModule;
+import org.killbill.billing.overdue.notification.OverdueAsyncBusNotificationKey;
+import org.killbill.billing.overdue.notification.OverdueAsyncBusNotificationKey.OverdueAsyncBusNotificationAction;
+import org.killbill.billing.overdue.notification.OverdueAsyncBusNotifier;
+import org.killbill.billing.overdue.notification.OverduePoster;
import org.killbill.billing.util.cache.Cachable.CacheType;
import org.killbill.billing.util.cache.CacheControllerDispatcher;
import org.killbill.billing.util.callcontext.CallOrigin;
@@ -36,6 +48,7 @@ import org.killbill.billing.util.callcontext.UserType;
import org.killbill.billing.util.dao.NonEntityDao;
import org.killbill.billing.util.tag.ControlTagType;
import org.killbill.bus.api.BusEvent;
+import org.killbill.clock.Clock;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -47,39 +60,40 @@ public class OverdueListener {
private static final Logger log = LoggerFactory.getLogger(OverdueListener.class);
- private final OverdueInternalApi overdueInternalApi;
private final InternalCallContextFactory internalCallContextFactory;
private final CacheControllerDispatcher cacheControllerDispatcher;
-
+ private final Clock clock;
+ private final OverduePoster asyncPoster;
+ private final OverdueConfigCache overdueConfigCache;
private final NonEntityDao nonEntityDao;
@Inject
- public OverdueListener(final OverdueInternalApi overdueInternalApi,
- final NonEntityDao nonEntityDao,
+ public OverdueListener(final NonEntityDao nonEntityDao,
final CacheControllerDispatcher cacheControllerDispatcher,
+ final Clock clock,
+ @Named(DefaultOverdueModule.OVERDUE_NOTIFIER_ASYNC_BUS_NAMED) final OverduePoster asyncPoster,
+ final OverdueConfigCache overdueConfigCache,
final InternalCallContextFactory internalCallContextFactory) {
- this.overdueInternalApi = overdueInternalApi;
this.nonEntityDao = nonEntityDao;
+ this.clock = clock;
+ this.asyncPoster = asyncPoster;
+ this.overdueConfigCache = overdueConfigCache;
this.cacheControllerDispatcher = cacheControllerDispatcher;
this.internalCallContextFactory = internalCallContextFactory;
}
-
-
-
@AllowConcurrentEvents
@Subscribe
public void handleTagInsert(final ControlTagCreationInternalEvent event) {
if (event.getTagDefinition().getName().equals(ControlTagType.OVERDUE_ENFORCEMENT_OFF.toString()) && event.getObjectType() == ObjectType.ACCOUNT) {
- final InternalCallContext callContext = createCallContext(event.getUserToken(), event.getSearchKey1(), event.getSearchKey2());
- overdueInternalApi.scheduleOverdueClear(event.getObjectId(), callContext);
+ final InternalCallContext internalCallContext = createCallContext(event.getUserToken(), event.getSearchKey1(), event.getSearchKey2());
+ insertBusEventIntoNotificationQueue(event.getObjectId(), OverdueAsyncBusNotificationAction.CLEAR, internalCallContext);
} else if (event.getTagDefinition().getName().equals(ControlTagType.WRITTEN_OFF.toString()) && event.getObjectType() == ObjectType.INVOICE) {
final UUID accountId = nonEntityDao.retrieveIdFromObject(event.getSearchKey1(), ObjectType.ACCOUNT, cacheControllerDispatcher.getCacheController(CacheType.OBJECT_ID));
insertBusEventIntoNotificationQueue(accountId, event);
}
}
-
@AllowConcurrentEvents
@Subscribe
public void handleTagRemoval(final ControlTagDeletionInternalEvent event) {
@@ -113,11 +127,42 @@ public class OverdueListener {
}
private void insertBusEventIntoNotificationQueue(final UUID accountId, final BusEvent event) {
- final InternalCallContext callContext = createCallContext(event.getUserToken(), event.getSearchKey1(), event.getSearchKey2());
- overdueInternalApi.scheduleOverdueRefresh(accountId, callContext);
+ final InternalCallContext internalCallContext = createCallContext(event.getUserToken(), event.getSearchKey1(), event.getSearchKey2());
+ insertBusEventIntoNotificationQueue(accountId, OverdueAsyncBusNotificationAction.REFRESH, internalCallContext);
}
private InternalCallContext createCallContext(final UUID userToken, final Long accountRecordId, final Long tenantRecordId) {
return internalCallContextFactory.createInternalCallContext(tenantRecordId, accountRecordId, "OverdueService", CallOrigin.INTERNAL, UserType.SYSTEM, userToken);
}
+
+ private void insertBusEventIntoNotificationQueue(final UUID accountId, final OverdueAsyncBusNotificationAction action, final InternalCallContext callContext) {
+ final boolean shouldInsertNotification = shouldInsertNotification(callContext);
+
+ if (shouldInsertNotification) {
+ final OverdueAsyncBusNotificationKey notificationKey = new OverdueAsyncBusNotificationKey(accountId, action);
+ asyncPoster.insertOverdueNotification(accountId, clock.getUTCNow(), OverdueAsyncBusNotifier.OVERDUE_ASYNC_BUS_NOTIFIER_QUEUE, notificationKey, callContext);
+ }
+ }
+
+ // Optimization: don't bother running the Overdue machinery if it's disabled
+ private boolean shouldInsertNotification(final InternalTenantContext internalTenantContext) {
+ OverdueConfig overdueConfig;
+ try {
+ overdueConfig = overdueConfigCache.getOverdueConfig(internalTenantContext);
+ } catch (final OverdueApiException e) {
+ log.warn("Failed to extract overdue config for tenant " + internalTenantContext.getTenantRecordId());
+ overdueConfig = null;
+ }
+ if (overdueConfig == null || overdueConfig.getOverdueStatesAccount() == null || overdueConfig.getOverdueStatesAccount().getStates() == null) {
+ return false;
+ }
+
+ for (final DefaultOverdueState state : ((DefaultOverdueConfig) overdueConfig).getOverdueStatesAccount().getStates()) {
+ if (state.getConditionEvaluation() != null) {
+ return true;
+ }
+ }
+ return false;
+ }
+
}
diff --git a/overdue/src/test/java/org/killbill/billing/overdue/OverdueTestSuiteNoDB.java b/overdue/src/test/java/org/killbill/billing/overdue/OverdueTestSuiteNoDB.java
index 8e90891..0e1f5e5 100644
--- a/overdue/src/test/java/org/killbill/billing/overdue/OverdueTestSuiteNoDB.java
+++ b/overdue/src/test/java/org/killbill/billing/overdue/OverdueTestSuiteNoDB.java
@@ -25,6 +25,7 @@ import org.killbill.billing.account.api.AccountInternalApi;
import org.killbill.billing.invoice.api.InvoiceInternalApi;
import org.killbill.billing.junction.BlockingInternalApi;
import org.killbill.billing.lifecycle.api.BusService;
+import org.killbill.billing.overdue.api.OverdueApi;
import org.killbill.billing.overdue.applicator.OverdueBusListenerTester;
import org.killbill.billing.overdue.applicator.OverdueStateApplicator;
import org.killbill.billing.overdue.caching.OverdueCacheInvalidationCallback;
@@ -86,7 +87,7 @@ public abstract class OverdueTestSuiteNoDB extends GuicyKillbillTestSuiteNoDB {
@Inject
protected OverdueStateApplicator applicator;
@Inject
- protected OverdueInternalApi overdueApi;
+ protected OverdueApi overdueApi;
@Inject
protected OverdueProperties overdueProperties;
@Inject
diff --git a/overdue/src/test/java/org/killbill/billing/overdue/OverdueTestSuiteWithEmbeddedDB.java b/overdue/src/test/java/org/killbill/billing/overdue/OverdueTestSuiteWithEmbeddedDB.java
index 1253410..f2b590d 100644
--- a/overdue/src/test/java/org/killbill/billing/overdue/OverdueTestSuiteWithEmbeddedDB.java
+++ b/overdue/src/test/java/org/killbill/billing/overdue/OverdueTestSuiteWithEmbeddedDB.java
@@ -25,6 +25,7 @@ import org.killbill.billing.account.api.AccountInternalApi;
import org.killbill.billing.invoice.api.InvoiceInternalApi;
import org.killbill.billing.junction.BlockingInternalApi;
import org.killbill.billing.lifecycle.api.BusService;
+import org.killbill.billing.overdue.api.OverdueApi;
import org.killbill.billing.overdue.applicator.OverdueBusListenerTester;
import org.killbill.billing.overdue.applicator.OverdueStateApplicator;
import org.killbill.billing.overdue.caching.OverdueConfigCache;
@@ -87,7 +88,7 @@ public abstract class OverdueTestSuiteWithEmbeddedDB extends GuicyKillbillTestSu
@Inject
protected OverdueStateApplicator applicator;
@Inject
- protected OverdueInternalApi overdueApi;
+ protected OverdueApi overdueApi;
@Inject
protected OverdueProperties overdueProperties;
@Inject
diff --git a/util/src/test/java/org/killbill/billing/mock/glue/MockOverdueModule.java b/util/src/test/java/org/killbill/billing/mock/glue/MockOverdueModule.java
index 0a88273..381bb9e 100644
--- a/util/src/test/java/org/killbill/billing/mock/glue/MockOverdueModule.java
+++ b/util/src/test/java/org/killbill/billing/mock/glue/MockOverdueModule.java
@@ -19,9 +19,7 @@
package org.killbill.billing.mock.glue;
import org.killbill.billing.glue.OverdueModule;
-import org.killbill.billing.overdue.OverdueInternalApi;
import org.killbill.billing.overdue.api.OverdueApi;
-import org.killbill.billing.overdue.api.OverdueConfig;
import org.killbill.billing.platform.api.KillbillConfigSource;
import org.killbill.billing.util.glue.KillBillModule;
import org.mockito.Mockito;
@@ -37,11 +35,9 @@ public class MockOverdueModule extends KillBillModule implements OverdueModule {
@Override
public void installOverdueUserApi() {
- bind(OverdueInternalApi.class).toInstance(Mockito.mock(OverdueInternalApi.class));
bind(OverdueApi.class).toInstance(Mockito.mock(OverdueApi.class));
}
-
@Override
protected void configure() {
installOverdueUserApi();