use of org.killbill.billing.overdue.api.OverdueApiException in project killbill by killbill.
the class EhCacheOverdueConfigCache method initializeCacheLoaderArgument.
private CacheLoaderArgument initializeCacheLoaderArgument() {
final LoaderCallback loaderCallback = new LoaderCallback() {
@Override
public Object loadOverdueConfig(final String overdueConfigXML) throws OverdueApiException {
final InputStream overdueConfigStream = new ByteArrayInputStream(overdueConfigXML.getBytes());
final URI uri;
try {
uri = new URI("/overdueConfig");
final DefaultOverdueConfig overdueConfig = XMLLoader.getObjectFromStream(uri, overdueConfigStream, DefaultOverdueConfig.class);
return overdueConfig;
} catch (final Exception e) {
throw new OverdueApiException(ErrorCode.OVERDUE_INVALID_FOR_TENANT, "Problem encountered loading overdue config ", e);
}
}
};
final Object[] args = new Object[1];
args[0] = loaderCallback;
final ObjectType irrelevant = null;
final InternalTenantContext notUsed = null;
return new CacheLoaderArgument(irrelevant, args, notUsed);
}
use of org.killbill.billing.overdue.api.OverdueApiException in project killbill by killbill.
the class EhCacheOverdueConfigCache method loadDefaultOverdueConfig.
@Override
public void loadDefaultOverdueConfig(@Nullable final String configURI) throws OverdueApiException {
boolean missingOrCorruptedDefaultConfig;
try {
if (configURI == null || configURI.isEmpty()) {
missingOrCorruptedDefaultConfig = true;
} else {
final URI u = new URI(configURI);
defaultOverdueConfig = XMLLoader.getObjectFromUri(u, DefaultOverdueConfig.class);
missingOrCorruptedDefaultConfig = (defaultOverdueConfig == null);
}
} catch (final Exception e) {
missingOrCorruptedDefaultConfig = true;
log.warn("Exception loading default overdue config from " + configURI, e);
}
if (missingOrCorruptedDefaultConfig) {
log.warn("Overdue system disabled: unable to load the overdue config from " + configURI);
}
}
use of org.killbill.billing.overdue.api.OverdueApiException in project killbill by killbill.
the class OverdueStateApplicator method clear.
public void clear(final DateTime effectiveDate, final ImmutableAccountData account, final OverdueState previousOverdueState, final OverdueState clearState, final InternalCallContext context) throws OverdueException {
log.debug("OverdueStateApplicator:clear : time = " + effectiveDate + ", previousState = " + previousOverdueState.getName());
storeNewState(effectiveDate, account, clearState, context);
clearFutureNotification(account, context);
try {
avoid_extra_credit_by_toggling_AUTO_INVOICE_OFF(account, previousOverdueState, clearState, context);
} catch (final OverdueApiException e) {
throw new OverdueException(e);
}
final OverdueChangeInternalEvent event;
try {
event = createOverdueEvent(account, previousOverdueState.getName(), clearState.getName(), isBlockBillingTransition(previousOverdueState, clearState), isUnblockBillingTransition(previousOverdueState, clearState), context);
} catch (final BlockingApiException e) {
log.warn("Failed to create OverdueChangeInternalEvent for accountId='{}'", account.getId(), e);
return;
}
try {
bus.post(event);
} catch (final Exception e) {
log.warn("Failed to post event {}", event, e);
}
}
use of org.killbill.billing.overdue.api.OverdueApiException in project killbill by killbill.
the class TenantOverdueConfigCacheLoader method load.
@Override
public Object load(final Object key, final Object argument) {
checkCacheLoaderStatus();
if (!(key instanceof Long)) {
throw new IllegalArgumentException("Unexpected key type of " + key.getClass().getName());
}
if (!(argument instanceof CacheLoaderArgument)) {
throw new IllegalArgumentException("Unexpected argument type of " + argument.getClass().getName());
}
final Long tenantRecordId = (Long) key;
final InternalTenantContext internalTenantContext = new InternalTenantContext(tenantRecordId);
final CacheLoaderArgument cacheLoaderArgument = (CacheLoaderArgument) argument;
if (cacheLoaderArgument.getArgs() == null || !(cacheLoaderArgument.getArgs()[0] instanceof LoaderCallback)) {
throw new IllegalArgumentException("Missing LoaderCallback from the arguments");
}
final LoaderCallback callback = (LoaderCallback) cacheLoaderArgument.getArgs()[0];
final String overdueXML = tenantApi.getTenantOverdueConfig(internalTenantContext);
if (overdueXML == null) {
return EMPTY_VALUE_PLACEHOLDER;
}
try {
log.info("Loading overdue cache for tenant " + internalTenantContext.getTenantRecordId());
return callback.loadOverdueConfig(overdueXML);
} catch (final OverdueApiException e) {
throw new IllegalStateException(String.format("Failed to de-serialize overdue config for tenant %s : %s", internalTenantContext.getTenantRecordId(), e.getMessage()), e);
}
}
use of org.killbill.billing.overdue.api.OverdueApiException in project killbill by killbill.
the class OverdueStateApplicator method apply.
public void apply(final DateTime effectiveDate, final OverdueStateSet overdueStateSet, final BillingState billingState, final ImmutableAccountData account, final OverdueState previousOverdueState, final OverdueState nextOverdueState, final InternalCallContext context) throws OverdueException, OverdueApiException {
try {
if (isAccountTaggedWith_OVERDUE_ENFORCEMENT_OFF(context)) {
log.debug("OverdueStateApplicator: apply returns because account (recordId={}) is set with OVERDUE_ENFORCEMENT_OFF", context.getAccountRecordId());
return;
}
log.debug("OverdueStateApplicator: time={}, previousState={}, nextState={}, billingState={}", effectiveDate, previousOverdueState, nextOverdueState, billingState);
final OverdueState firstOverdueState = overdueStateSet.getFirstState();
final boolean conditionForNextNotfication = !nextOverdueState.isClearState() || // We did not reach the first state yet but we have an unpaid invoice
(firstOverdueState != null && billingState != null && billingState.getDateOfEarliestUnpaidInvoice() != null);
if (conditionForNextNotfication) {
final Period reevaluationInterval = getReevaluationInterval(overdueStateSet, nextOverdueState);
// If there is no configuration in the config, we assume this is because the overdue conditions are not time based and so there is nothing to retry
if (reevaluationInterval == null) {
log.debug("OverdueStateApplicator <notificationQ>: missing InitialReevaluationInterval from config, NOT inserting notification for account {}", account.getId());
} else {
log.debug("OverdueStateApplicator <notificationQ>: inserting notification for account={}, time={}", account.getId(), effectiveDate.plus(reevaluationInterval));
createFutureNotification(account, effectiveDate.plus(reevaluationInterval), context);
}
} else if (nextOverdueState.isClearState()) {
clearFutureNotification(account, context);
}
if (previousOverdueState.getName().equals(nextOverdueState.getName())) {
log.debug("OverdueStateApplicator is no-op: previousState={}, nextState={}", previousOverdueState, nextOverdueState);
return;
}
cancelSubscriptionsIfRequired(effectiveDate, account, nextOverdueState, context);
sendEmailIfRequired(account.getId(), billingState, nextOverdueState, context);
avoid_extra_credit_by_toggling_AUTO_INVOICE_OFF(account, previousOverdueState, nextOverdueState, context);
// Make sure to store the new state last here: the entitlement DAO will send a BlockingTransitionInternalEvent
// on the bus to which invoice will react. We need the latest state (including AUTO_INVOICE_OFF tag for example)
// to be present in the database first.
storeNewState(effectiveDate, account, nextOverdueState, context);
} catch (final AccountApiException e) {
throw new OverdueException(e);
}
final OverdueChangeInternalEvent event;
try {
event = createOverdueEvent(account, previousOverdueState.getName(), nextOverdueState.getName(), isBlockBillingTransition(previousOverdueState, nextOverdueState), isUnblockBillingTransition(previousOverdueState, nextOverdueState), context);
} catch (final BlockingApiException e) {
log.warn("Failed to create OverdueChangeInternalEvent for accountId='{}'", account.getId(), e);
return;
}
try {
bus.post(event);
} catch (final Exception e) {
log.warn("Failed to post event {}", event, e);
}
}
Aggregations