killbill-memoizeit
util: fix potential cross-tenants queries in InternalCallContextFactory Restrict …
Changes
entitlement/src/main/java/org/killbill/billing/entitlement/api/DefaultSubscriptionApi.java 26(+9 -17)
entitlement/src/main/java/org/killbill/billing/entitlement/DefaultEntitlementService.java 39(+16 -23)
invoice/src/main/java/org/killbill/billing/invoice/generator/DefaultInvoiceGenerator.java 27(+12 -15)
invoice/src/main/java/org/killbill/billing/invoice/notification/DefaultNextBillingDateNotifier.java 15(+7 -8)
invoice/src/main/java/org/killbill/billing/invoice/notification/DefaultNextBillingDatePoster.java 55(+13 -42)
invoice/src/main/java/org/killbill/billing/invoice/notification/NextBillingDatePoster.java 11(+5 -6)
invoice/src/test/java/org/killbill/billing/invoice/generator/TestDefaultInvoiceGenerator.java 6(+4 -2)
invoice/src/test/java/org/killbill/billing/invoice/notification/MockNextBillingDateNotifier.java 35(+0 -35)
invoice/src/test/java/org/killbill/billing/invoice/notification/MockNextBillingDatePoster.java 36(+0 -36)
overdue/src/main/java/org/killbill/billing/overdue/applicator/OverdueStateApplicator.java 58(+28 -30)
payment/src/main/java/org/killbill/billing/payment/core/janitor/AttemptCompletionTask.java 21(+9 -12)
payment/src/main/java/org/killbill/billing/payment/core/janitor/PendingTransactionTask.java 15(+6 -9)
payment/src/main/java/org/killbill/billing/payment/core/PluginRoutingPaymentProcessor.java 22(+8 -14)
payment/src/main/java/org/killbill/billing/payment/invoice/InvoicePaymentRoutingPluginApi.java 37(+19 -18)
subscription/src/main/java/org/killbill/billing/subscription/api/svcs/DefaultSubscriptionInternalApi.java 74(+34 -40)
subscription/src/main/java/org/killbill/billing/subscription/engine/core/DefaultSubscriptionBaseService.java 30(+9 -21)
Details
diff --git a/beatrix/src/main/java/org/killbill/billing/beatrix/extbus/BeatrixListener.java b/beatrix/src/main/java/org/killbill/billing/beatrix/extbus/BeatrixListener.java
index 3840cd5..c0b2f2f 100644
--- a/beatrix/src/main/java/org/killbill/billing/beatrix/extbus/BeatrixListener.java
+++ b/beatrix/src/main/java/org/killbill/billing/beatrix/extbus/BeatrixListener.java
@@ -1,7 +1,9 @@
/*
* Copyright 2010-2013 Ning, Inc.
+ * Copyright 2014-2015 Groupon, Inc
+ * Copyright 2014-2015 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:
*
@@ -22,7 +24,6 @@ import javax.inject.Inject;
import javax.inject.Named;
import org.killbill.billing.ObjectType;
-import org.killbill.billing.account.api.AccountInternalApi;
import org.killbill.billing.callcontext.InternalCallContext;
import org.killbill.billing.entitlement.EntitlementTransitionType;
import org.killbill.billing.events.AccountChangeInternalEvent;
@@ -46,12 +47,10 @@ import org.killbill.billing.events.UserTagDeletionInternalEvent;
import org.killbill.billing.lifecycle.glue.BusModule;
import org.killbill.billing.notification.plugin.api.ExtBusEventType;
import org.killbill.billing.subscription.api.SubscriptionBaseTransitionType;
-import org.killbill.billing.util.cache.Cachable.CacheType;
-import org.killbill.billing.util.cache.CacheControllerDispatcher;
import org.killbill.billing.util.callcontext.CallOrigin;
import org.killbill.billing.util.callcontext.InternalCallContextFactory;
+import org.killbill.billing.util.callcontext.TenantContext;
import org.killbill.billing.util.callcontext.UserType;
-import org.killbill.billing.util.dao.NonEntityDao;
import org.killbill.bus.api.BusEvent;
import org.killbill.bus.api.PersistentBus;
import org.killbill.bus.api.PersistentBus.EventBusException;
@@ -70,23 +69,14 @@ public class BeatrixListener {
private final PersistentBus externalBus;
private final InternalCallContextFactory internalCallContextFactory;
- private final AccountInternalApi accountApi;
- private final NonEntityDao nonEntityDao;
- private final CacheControllerDispatcher cacheControllerDispatcher;
protected final ObjectMapper objectMapper;
@Inject
public BeatrixListener(@Named(BusModule.EXTERNAL_BUS_NAMED) final PersistentBus externalBus,
- final InternalCallContextFactory internalCallContextFactory,
- final AccountInternalApi accountApi,
- final CacheControllerDispatcher cacheControllerDispatcher,
- final NonEntityDao nonEntityDao) {
+ final InternalCallContextFactory internalCallContextFactory) {
this.externalBus = externalBus;
this.internalCallContextFactory = internalCallContextFactory;
- this.accountApi = accountApi;
- this.nonEntityDao = nonEntityDao;
- this.cacheControllerDispatcher = cacheControllerDispatcher;
this.objectMapper = new ObjectMapper();
objectMapper.registerModule(new JodaModule());
objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
@@ -243,19 +233,20 @@ public class BeatrixListener {
default:
}
- final UUID accountId = getAccountIdFromRecordId(event.getBusEventType(), objectId, context.getAccountRecordId());
- final UUID tenantId = nonEntityDao.retrieveIdFromObject(context.getTenantRecordId(), ObjectType.TENANT, cacheControllerDispatcher.getCacheController(CacheType.OBJECT_ID));
+
+ final TenantContext tenantContext = internalCallContextFactory.createTenantContext(context);
+ final UUID accountId = getAccountId(event.getBusEventType(), objectId, objectType, tenantContext);
return eventBusType != null ?
- new DefaultBusExternalEvent(objectId, objectType, eventBusType, accountId, tenantId, context.getAccountRecordId(), context.getTenantRecordId(), context.getUserToken()) :
+ new DefaultBusExternalEvent(objectId, objectType, eventBusType, accountId, tenantContext.getTenantId(), context.getAccountRecordId(), context.getTenantRecordId(), context.getUserToken()) :
null;
}
- private UUID getAccountIdFromRecordId(final BusInternalEventType eventType, final UUID objectId, final Long recordId) {
+ private UUID getAccountId(final BusInternalEventType eventType, final UUID objectId, final ObjectType objectType, final TenantContext context) {
// accountRecord_id is not set for ACCOUNT_CREATE event as we are in the transaction and value is known yet
if (eventType == BusInternalEventType.ACCOUNT_CREATE) {
return objectId;
}
- return nonEntityDao.retrieveIdFromObject(recordId, ObjectType.ACCOUNT, cacheControllerDispatcher.getCacheController(CacheType.OBJECT_ID));
+ return internalCallContextFactory.getAccountId(objectId, objectType, context);
}
}
diff --git a/entitlement/src/main/java/org/killbill/billing/entitlement/api/DefaultSubscriptionApi.java b/entitlement/src/main/java/org/killbill/billing/entitlement/api/DefaultSubscriptionApi.java
index a96d33a..8da4329 100644
--- a/entitlement/src/main/java/org/killbill/billing/entitlement/api/DefaultSubscriptionApi.java
+++ b/entitlement/src/main/java/org/killbill/billing/entitlement/api/DefaultSubscriptionApi.java
@@ -1,7 +1,9 @@
/*
* Copyright 2010-2013 Ning, Inc.
+ * Copyright 2014-2015 Groupon, Inc
+ * Copyright 2014-2015 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:
*
@@ -27,9 +29,6 @@ import java.util.UUID;
import javax.inject.Inject;
import org.joda.time.DateTimeZone;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
import org.killbill.billing.ErrorCode;
import org.killbill.billing.ObjectType;
import org.killbill.billing.callcontext.InternalCallContext;
@@ -41,15 +40,14 @@ import org.killbill.billing.subscription.api.SubscriptionBase;
import org.killbill.billing.subscription.api.SubscriptionBaseInternalApi;
import org.killbill.billing.subscription.api.user.SubscriptionBaseApiException;
import org.killbill.billing.subscription.api.user.SubscriptionBaseBundle;
-import org.killbill.billing.util.cache.Cachable.CacheType;
-import org.killbill.billing.util.cache.CacheControllerDispatcher;
import org.killbill.billing.util.callcontext.CallContext;
import org.killbill.billing.util.callcontext.InternalCallContextFactory;
import org.killbill.billing.util.callcontext.TenantContext;
import org.killbill.billing.util.customfield.ShouldntHappenException;
-import org.killbill.billing.util.dao.NonEntityDao;
import org.killbill.billing.util.entity.Pagination;
import org.killbill.billing.util.entity.dao.DefaultPaginationHelper.SourcePaginationBuilder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import com.google.common.base.Function;
import com.google.common.base.Optional;
@@ -85,31 +83,26 @@ public class DefaultSubscriptionApi implements SubscriptionApi {
private final EntitlementInternalApi entitlementInternalApi;
private final SubscriptionBaseInternalApi subscriptionBaseInternalApi;
private final InternalCallContextFactory internalCallContextFactory;
- private final NonEntityDao nonEntityDao;
- private final CacheControllerDispatcher cacheControllerDispatcher;
private final EntitlementUtils entitlementUtils;
@Inject
public DefaultSubscriptionApi(final EntitlementInternalApi entitlementInternalApi, final SubscriptionBaseInternalApi subscriptionInternalApi,
- final InternalCallContextFactory internalCallContextFactory, final EntitlementUtils entitlementUtils, final NonEntityDao nonEntityDao, final CacheControllerDispatcher cacheControllerDispatcher) {
+ final InternalCallContextFactory internalCallContextFactory, final EntitlementUtils entitlementUtils) {
this.entitlementInternalApi = entitlementInternalApi;
this.subscriptionBaseInternalApi = subscriptionInternalApi;
this.internalCallContextFactory = internalCallContextFactory;
- this.nonEntityDao = nonEntityDao;
this.entitlementUtils = entitlementUtils;
- this.cacheControllerDispatcher = cacheControllerDispatcher;
}
@Override
public Subscription getSubscriptionForEntitlementId(final UUID entitlementId, final TenantContext context) throws SubscriptionApiException {
- final Long accountRecordId = nonEntityDao.retrieveAccountRecordIdFromObject(entitlementId, ObjectType.SUBSCRIPTION, cacheControllerDispatcher.getCacheController(CacheType.ACCOUNT_RECORD_ID));
- final UUID accountId = nonEntityDao.retrieveIdFromObject(accountRecordId, ObjectType.ACCOUNT, cacheControllerDispatcher.getCacheController(CacheType.OBJECT_ID));
+ final UUID accountId = internalCallContextFactory.getAccountId(entitlementId, ObjectType.SUBSCRIPTION, context);
// Retrieve entitlements
final AccountEntitlements accountEntitlements;
try {
accountEntitlements = entitlementInternalApi.getAllEntitlementsForAccountId(accountId, context);
- } catch (EntitlementApiException e) {
+ } catch (final EntitlementApiException e) {
throw new SubscriptionApiException(e);
}
@@ -127,8 +120,7 @@ public class DefaultSubscriptionApi implements SubscriptionApi {
@Override
public SubscriptionBundle getSubscriptionBundle(final UUID bundleId, final TenantContext context) throws SubscriptionApiException {
- final Long accountRecordId = nonEntityDao.retrieveAccountRecordIdFromObject(bundleId, ObjectType.BUNDLE, cacheControllerDispatcher.getCacheController(CacheType.ACCOUNT_RECORD_ID));
- final UUID accountId = nonEntityDao.retrieveIdFromObject(accountRecordId, ObjectType.ACCOUNT, cacheControllerDispatcher.getCacheController(CacheType.OBJECT_ID));
+ final UUID accountId = internalCallContextFactory.getAccountId(bundleId, ObjectType.BUNDLE, context);
final Optional<SubscriptionBundle> bundleOptional = Iterables.<SubscriptionBundle>tryFind(getSubscriptionBundlesForAccount(accountId, context),
new Predicate<SubscriptionBundle>() {
diff --git a/entitlement/src/main/java/org/killbill/billing/entitlement/DefaultEntitlementService.java b/entitlement/src/main/java/org/killbill/billing/entitlement/DefaultEntitlementService.java
index ca86524..389f75c 100644
--- a/entitlement/src/main/java/org/killbill/billing/entitlement/DefaultEntitlementService.java
+++ b/entitlement/src/main/java/org/killbill/billing/entitlement/DefaultEntitlementService.java
@@ -1,7 +1,7 @@
/*
* Copyright 2010-2013 Ning, Inc.
- * Copyright 2014 Groupon, Inc
- * Copyright 2014 The Billing Project, LLC
+ * Copyright 2014-2015 Groupon, Inc
+ * Copyright 2014-2015 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
@@ -21,7 +21,6 @@ package org.killbill.billing.entitlement;
import java.util.UUID;
import org.joda.time.DateTime;
-import org.killbill.billing.ObjectType;
import org.killbill.billing.callcontext.InternalCallContext;
import org.killbill.billing.entitlement.api.DefaultBlockingTransitionInternalEvent;
import org.killbill.billing.entitlement.api.DefaultEntitlement;
@@ -34,12 +33,10 @@ import org.killbill.billing.entitlement.engine.core.EntitlementNotificationKey;
import org.killbill.billing.entitlement.engine.core.EntitlementNotificationKeyAction;
import org.killbill.billing.platform.api.LifecycleHandlerType;
import org.killbill.billing.platform.api.LifecycleHandlerType.LifecycleLevel;
-import org.killbill.billing.util.cache.Cachable.CacheType;
-import org.killbill.billing.util.cache.CacheControllerDispatcher;
+import org.killbill.billing.util.callcontext.CallContext;
import org.killbill.billing.util.callcontext.CallOrigin;
import org.killbill.billing.util.callcontext.InternalCallContextFactory;
import org.killbill.billing.util.callcontext.UserType;
-import org.killbill.billing.util.dao.NonEntityDao;
import org.killbill.bus.api.BusEvent;
import org.killbill.bus.api.PersistentBus;
import org.killbill.bus.api.PersistentBus.EventBusException;
@@ -62,29 +59,23 @@ public class DefaultEntitlementService implements EntitlementService {
private final EntitlementApi entitlementApi;
private final BlockingStateDao blockingStateDao;
- private final NonEntityDao nonEntityDao;
private final PersistentBus eventBus;
private final NotificationQueueService notificationQueueService;
private final InternalCallContextFactory internalCallContextFactory;
- private final CacheControllerDispatcher controllerDispatcher;
private NotificationQueue entitlementEventQueue;
@Inject
public DefaultEntitlementService(final EntitlementApi entitlementApi,
final BlockingStateDao blockingStateDao,
- final NonEntityDao nonEntityDao,
final PersistentBus eventBus,
final NotificationQueueService notificationQueueService,
- final InternalCallContextFactory internalCallContextFactory,
- final CacheControllerDispatcher controllerDispatcher) {
+ final InternalCallContextFactory internalCallContextFactory) {
this.entitlementApi = entitlementApi;
this.blockingStateDao = blockingStateDao;
- this.nonEntityDao = nonEntityDao;
this.eventBus = eventBus;
this.notificationQueueService = notificationQueueService;
this.internalCallContextFactory = internalCallContextFactory;
- this.controllerDispatcher = controllerDispatcher;
}
@Override
@@ -101,8 +92,8 @@ public class DefaultEntitlementService implements EntitlementService {
final InternalCallContext internalCallContext = internalCallContextFactory.createInternalCallContext(tenantRecordId, accountRecordId, "EntitlementQueue", CallOrigin.INTERNAL, UserType.SYSTEM, fromNotificationQueueUserToken);
if (inputKey instanceof EntitlementNotificationKey) {
- final UUID tenantId = nonEntityDao.retrieveIdFromObject(tenantRecordId, ObjectType.TENANT, controllerDispatcher.getCacheController(CacheType.OBJECT_ID));
- processEntitlementNotification((EntitlementNotificationKey) inputKey, tenantId, internalCallContext);
+ final CallContext callContext = internalCallContextFactory.createCallContext(internalCallContext);
+ processEntitlementNotification((EntitlementNotificationKey) inputKey, internalCallContext, callContext);
} else if (inputKey instanceof BlockingTransitionNotificationKey) {
processBlockingNotification((BlockingTransitionNotificationKey) inputKey, internalCallContext);
} else if (inputKey != null) {
@@ -121,10 +112,10 @@ public class DefaultEntitlementService implements EntitlementService {
}
}
- private void processEntitlementNotification(final EntitlementNotificationKey key, final UUID tenantId, final InternalCallContext internalCallContext) {
+ private void processEntitlementNotification(final EntitlementNotificationKey key, final InternalCallContext internalCallContext, final CallContext callContext) {
final Entitlement entitlement;
try {
- entitlement = entitlementApi.getEntitlementForId(key.getEntitlementId(), internalCallContext.toTenantContext(tenantId));
+ entitlement = entitlementApi.getEntitlementForId(key.getEntitlementId(), callContext);
} catch (final EntitlementApiException e) {
log.error("Error retrieving entitlement for id " + key.getEntitlementId(), e);
return;
@@ -139,11 +130,13 @@ public class DefaultEntitlementService implements EntitlementService {
try {
if (EntitlementNotificationKeyAction.CHANGE.equals(entitlementNotificationKeyAction) ||
EntitlementNotificationKeyAction.CANCEL.equals(entitlementNotificationKeyAction)) {
- ((DefaultEntitlement) entitlement).blockAddOnsIfRequired(key.getEffectiveDate(), internalCallContext.toTenantContext(tenantId), internalCallContext);
- } else if (EntitlementNotificationKeyAction.PAUSE.equals(entitlementNotificationKeyAction)) {
- entitlementApi.pause(key.getBundleId(), key.getEffectiveDate().toLocalDate(), internalCallContext.toCallContext(tenantId));
- } else if (EntitlementNotificationKeyAction.RESUME.equals(entitlementNotificationKeyAction)) {
- entitlementApi.resume(key.getBundleId(), key.getEffectiveDate().toLocalDate(), internalCallContext.toCallContext(tenantId));
+ ((DefaultEntitlement) entitlement).blockAddOnsIfRequired(key.getEffectiveDate(), callContext, internalCallContext);
+ } else {
+ if (EntitlementNotificationKeyAction.PAUSE.equals(entitlementNotificationKeyAction)) {
+ entitlementApi.pause(key.getBundleId(), key.getEffectiveDate().toLocalDate(), callContext);
+ } else if (EntitlementNotificationKeyAction.RESUME.equals(entitlementNotificationKeyAction)) {
+ entitlementApi.resume(key.getBundleId(), key.getEffectiveDate().toLocalDate(), callContext);
+ }
}
} catch (final EntitlementApiException e) {
log.error("Error processing event for entitlement {}" + entitlement.getId(), e);
@@ -164,7 +157,7 @@ public class DefaultEntitlementService implements EntitlementService {
try {
eventBus.post(event);
- } catch (EventBusException e) {
+ } catch (final EventBusException e) {
log.warn("Failed to post event {}", e);
}
}
diff --git a/entitlement/src/test/java/org/killbill/billing/entitlement/block/TestBlockingApi.java b/entitlement/src/test/java/org/killbill/billing/entitlement/block/TestBlockingApi.java
index e97bda7..28e0e04 100644
--- a/entitlement/src/test/java/org/killbill/billing/entitlement/block/TestBlockingApi.java
+++ b/entitlement/src/test/java/org/killbill/billing/entitlement/block/TestBlockingApi.java
@@ -1,7 +1,9 @@
/*
* Copyright 2010-2013 Ning, Inc.
+ * Copyright 2014-2015 Groupon, Inc
+ * Copyright 2014-2015 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:
*
@@ -19,10 +21,6 @@ package org.killbill.billing.entitlement.block;
import java.util.List;
import java.util.UUID;
-import org.testng.Assert;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
import org.killbill.billing.account.api.Account;
import org.killbill.billing.api.TestApiListener.NextEvent;
import org.killbill.billing.callcontext.InternalCallContext;
@@ -30,8 +28,9 @@ import org.killbill.billing.entitlement.EntitlementTestSuiteWithEmbeddedDB;
import org.killbill.billing.entitlement.api.BlockingState;
import org.killbill.billing.entitlement.api.BlockingStateType;
import org.killbill.billing.junction.DefaultBlockingState;
-import org.killbill.billing.util.callcontext.CallOrigin;
-import org.killbill.billing.util.callcontext.UserType;
+import org.testng.Assert;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
import com.google.common.base.Predicate;
import com.google.common.collect.Collections2;
@@ -82,7 +81,7 @@ public class TestBlockingApi extends EntitlementTestSuiteWithEmbeddedDB {
final boolean blockBilling = false;
final Account account = accountApi.createAccount(getAccountData(7), callContext);
- final InternalCallContext internalCallContext = internalCallContextFactory.createInternalCallContext(account.getId(), "TestBlockingApi", CallOrigin.TEST, UserType.SYSTEM, UUID.randomUUID());
+ final InternalCallContext internalCallContext = internalCallContextFactory.createInternalCallContext(account.getId(), callContext);
testListener.pushExpectedEvent(NextEvent.BLOCK);
final BlockingState state1 = new DefaultBlockingState(uuid, BlockingStateType.ACCOUNT, overdueStateName, service, blockChange, blockEntitlement, blockBilling, clock.getUTCNow());
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/dao/DefaultInvoiceDao.java b/invoice/src/main/java/org/killbill/billing/invoice/dao/DefaultInvoiceDao.java
index d128afd..cd2e38d 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/dao/DefaultInvoiceDao.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/dao/DefaultInvoiceDao.java
@@ -1,7 +1,9 @@
/*
* Copyright 2010-2013 Ning, Inc.
+ * Copyright 2014-2015 Groupon, Inc
+ * Copyright 2014-2015 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:
*
@@ -127,7 +129,6 @@ public class DefaultInvoiceDao extends EntityDaoBase<InvoiceModelDao, Invoice, I
});
}
-
@Override
public List<InvoiceModelDao> getAllInvoicesByAccount(final InternalTenantContext context) {
return transactionalSqlDao.execute(new EntitySqlDaoTransactionWrapper<List<InvoiceModelDao>>() {
@@ -230,7 +231,7 @@ public class DefaultInvoiceDao extends EntityDaoBase<InvoiceModelDao, Invoice, I
cbaDao.addCBAComplexityFromTransaction(invoice, entitySqlDaoWrapperFactory, context);
- notifyOfFutureBillingEvents(entitySqlDaoWrapperFactory, invoice.getAccountId(), callbackDateTimePerSubscriptions, context.getUserToken());
+ notifyOfFutureBillingEvents(entitySqlDaoWrapperFactory, invoice.getAccountId(), callbackDateTimePerSubscriptions, context);
}
return null;
}
@@ -401,7 +402,7 @@ public class DefaultInvoiceDao extends EntityDaoBase<InvoiceModelDao, Invoice, I
// Retrieve invoice after the Refund
final InvoiceModelDao invoice = transInvoiceDao.getById(payment.getInvoiceId().toString(), context);
- Preconditions.checkState(invoice != null, "Invoice shouldn't be null for payment " + payment.getId());
+ Preconditions.checkState(invoice != null, "Invoice shouldn't be null for payment " + payment.getId());
invoiceDaoHelper.populateChildren(invoice, entitySqlDaoWrapperFactory, context);
final BigDecimal invoiceBalanceAfterRefund = InvoiceModelDaoHelper.getBalance(invoice);
@@ -507,7 +508,6 @@ public class DefaultInvoiceDao extends EntityDaoBase<InvoiceModelDao, Invoice, I
});
}
-
@Override
public BigDecimal getRemainingAmountPaid(final UUID invoicePaymentId, final InternalTenantContext context) {
return transactionalSqlDao.execute(new EntitySqlDaoTransactionWrapper<BigDecimal>() {
@@ -840,11 +840,11 @@ public class DefaultInvoiceDao extends EntityDaoBase<InvoiceModelDao, Invoice, I
}
private void notifyOfFutureBillingEvents(final EntitySqlDaoWrapperFactory<EntitySqlDao> entitySqlDaoWrapperFactory, final UUID accountId,
- final Map<UUID, List<DateTime>> callbackDateTimePerSubscriptions, final UUID userToken) {
+ final Map<UUID, List<DateTime>> callbackDateTimePerSubscriptions, final InternalCallContext internalCallContext) {
for (final UUID subscriptionId : callbackDateTimePerSubscriptions.keySet()) {
final List<DateTime> callbackDateTimeUTC = callbackDateTimePerSubscriptions.get(subscriptionId);
- for (DateTime cur : callbackDateTimeUTC) {
- nextBillingDatePoster.insertNextBillingNotificationFromTransaction(entitySqlDaoWrapperFactory, accountId, subscriptionId, cur, userToken);
+ for (final DateTime cur : callbackDateTimeUTC) {
+ nextBillingDatePoster.insertNextBillingNotificationFromTransaction(entitySqlDaoWrapperFactory, accountId, subscriptionId, cur, internalCallContext);
}
}
}
@@ -854,7 +854,7 @@ public class DefaultInvoiceDao extends EntityDaoBase<InvoiceModelDao, Invoice, I
try {
eventBus.postFromTransaction(new DefaultInvoiceAdjustmentEvent(invoiceId, accountId, context.getAccountRecordId(), context.getTenantRecordId(), userToken),
entitySqlDaoWrapperFactory.getSqlDao());
- } catch (EventBusException e) {
+ } catch (final EventBusException e) {
log.warn("Failed to post adjustment event for invoice " + invoiceId, e);
}
}
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/generator/DefaultInvoiceGenerator.java b/invoice/src/main/java/org/killbill/billing/invoice/generator/DefaultInvoiceGenerator.java
index ccd7440..9116ba0 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/generator/DefaultInvoiceGenerator.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/generator/DefaultInvoiceGenerator.java
@@ -1,7 +1,9 @@
/*
* Copyright 2010-2013 Ning, Inc.
+ * Copyright 2014-2015 Groupon, Inc
+ * Copyright 2014-2015 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:
*
@@ -28,7 +30,6 @@ import javax.annotation.Nullable;
import org.joda.time.LocalDate;
import org.joda.time.Months;
import org.killbill.billing.ErrorCode;
-import org.killbill.billing.ObjectType;
import org.killbill.billing.callcontext.InternalCallContext;
import org.killbill.billing.catalog.api.BillingMode;
import org.killbill.billing.catalog.api.BillingPeriod;
@@ -50,11 +51,10 @@ import org.killbill.billing.invoice.usage.SubscriptionConsumableInArrear;
import org.killbill.billing.junction.BillingEvent;
import org.killbill.billing.junction.BillingEventSet;
import org.killbill.billing.usage.api.UsageUserApi;
-import org.killbill.billing.util.cache.Cachable.CacheType;
-import org.killbill.billing.util.cache.CacheControllerDispatcher;
+import org.killbill.billing.util.callcontext.InternalCallContextFactory;
+import org.killbill.billing.util.callcontext.TenantContext;
import org.killbill.billing.util.config.InvoiceConfig;
import org.killbill.billing.util.currency.KillBillMoney;
-import org.killbill.billing.util.dao.NonEntityDao;
import org.killbill.clock.Clock;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -73,16 +73,14 @@ public class DefaultInvoiceGenerator implements InvoiceGenerator {
private final Clock clock;
private final InvoiceConfig config;
private final UsageUserApi usageApi;
- private final NonEntityDao nonEntityDao;
- private final CacheControllerDispatcher controllerDispatcher;
+ private final InternalCallContextFactory internalCallContextFactory;
@Inject
- public DefaultInvoiceGenerator(final Clock clock, final UsageUserApi usageApi, final InvoiceConfig config, final NonEntityDao nonEntityDao, final CacheControllerDispatcher controllerDispatcher) {
+ public DefaultInvoiceGenerator(final Clock clock, final UsageUserApi usageApi, final InvoiceConfig config, final InternalCallContextFactory internalCallContextFactory) {
this.clock = clock;
this.config = config;
this.usageApi = usageApi;
- this.nonEntityDao = nonEntityDao;
- this.controllerDispatcher = controllerDispatcher;
+ this.internalCallContextFactory = internalCallContextFactory;
}
/*
@@ -116,8 +114,7 @@ public class DefaultInvoiceGenerator implements InvoiceGenerator {
private List<InvoiceItem> generateUsageInvoiceItems(final UUID invoiceId, final BillingEventSet eventSet,
@Nullable final List<Invoice> existingInvoices, final LocalDate targetDate,
final InternalCallContext context) throws InvoiceApiException {
-
- final UUID tenantId = nonEntityDao.retrieveIdFromObject(context.getTenantRecordId(), ObjectType.TENANT, controllerDispatcher.getCacheController(CacheType.OBJECT_ID));
+ final TenantContext tenantContext = internalCallContextFactory.createTenantContext(context);
try {
final List<InvoiceItem> items = Lists.newArrayList();
@@ -128,14 +125,14 @@ public class DefaultInvoiceGenerator implements InvoiceGenerator {
while (events.hasNext()) {
final BillingEvent event = events.next();
// Skip events that are posterior to the targetDate
- final LocalDate eventLocalEffectiveDate = new LocalDate(event.getEffectiveDate(), event.getAccount().getTimeZone());
+ final LocalDate eventLocalEffectiveDate = new LocalDate(event.getEffectiveDate(), event.getAccount().getTimeZone());
if (eventLocalEffectiveDate.isAfter(targetDate)) {
continue;
}
final UUID subscriptionId = event.getSubscription().getId();
if (curSubscriptionId != null && !curSubscriptionId.equals(subscriptionId)) {
- final SubscriptionConsumableInArrear subscriptionConsumableInArrear = new SubscriptionConsumableInArrear(invoiceId, curEvents, usageApi, config.isInsertZeroUsageItems(), targetDate, context.toTenantContext(tenantId));
+ final SubscriptionConsumableInArrear subscriptionConsumableInArrear = new SubscriptionConsumableInArrear(invoiceId, curEvents, usageApi, config.isInsertZeroUsageItems(), targetDate, tenantContext);
items.addAll(subscriptionConsumableInArrear.computeMissingUsageInvoiceItems(extractUsageItemsForSubscription(curSubscriptionId, existingInvoices)));
curEvents = Lists.newArrayList();
}
@@ -143,7 +140,7 @@ public class DefaultInvoiceGenerator implements InvoiceGenerator {
curEvents.add(event);
}
if (curSubscriptionId != null) {
- final SubscriptionConsumableInArrear subscriptionConsumableInArrear = new SubscriptionConsumableInArrear(invoiceId, curEvents, usageApi, config.isInsertZeroUsageItems(), targetDate, context.toTenantContext(tenantId));
+ final SubscriptionConsumableInArrear subscriptionConsumableInArrear = new SubscriptionConsumableInArrear(invoiceId, curEvents, usageApi, config.isInsertZeroUsageItems(), targetDate, tenantContext);
items.addAll(subscriptionConsumableInArrear.computeMissingUsageInvoiceItems(extractUsageItemsForSubscription(curSubscriptionId, existingInvoices)));
}
return items;
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/InvoiceDispatcher.java b/invoice/src/main/java/org/killbill/billing/invoice/InvoiceDispatcher.java
index 8debd89..4a0e1a9 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/InvoiceDispatcher.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/InvoiceDispatcher.java
@@ -1,7 +1,7 @@
/*
* Copyright 2010-2013 Ning, Inc.
- * Copyright 2014 Groupon, Inc
- * Copyright 2014 The Billing Project, LLC
+ * Copyright 2014-2015 Groupon, Inc
+ * Copyright 2014-2015 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
@@ -33,18 +33,15 @@ import javax.annotation.Nullable;
import org.joda.time.DateTime;
import org.joda.time.LocalDate;
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.catalog.api.BillingMode;
-import org.killbill.billing.catalog.api.BillingPeriod;
import org.killbill.billing.catalog.api.CatalogApiException;
import org.killbill.billing.catalog.api.Currency;
import org.killbill.billing.catalog.api.Usage;
-import org.killbill.billing.entitlement.api.SubscriptionEventType;
import org.killbill.billing.events.BusInternalEvent;
import org.killbill.billing.events.EffectiveSubscriptionInternalEvent;
import org.killbill.billing.events.InvoiceAdjustmentInternalEvent;
@@ -73,11 +70,9 @@ import org.killbill.billing.osgi.api.OSGIServiceRegistration;
import org.killbill.billing.payment.api.PluginProperty;
import org.killbill.billing.subscription.api.SubscriptionBaseInternalApi;
import org.killbill.billing.subscription.api.user.SubscriptionBaseApiException;
-import org.killbill.billing.util.cache.Cachable.CacheType;
-import org.killbill.billing.util.cache.CacheControllerDispatcher;
import org.killbill.billing.util.callcontext.CallContext;
+import org.killbill.billing.util.callcontext.InternalCallContextFactory;
import org.killbill.billing.util.callcontext.TenantContext;
-import org.killbill.billing.util.dao.NonEntityDao;
import org.killbill.billing.util.globallocker.LockerType;
import org.killbill.billing.util.timezone.DateAndTimeZoneContext;
import org.killbill.bus.api.PersistentBus;
@@ -106,37 +101,36 @@ public class InvoiceDispatcher {
private final AccountInternalApi accountApi;
private final SubscriptionBaseInternalApi subscriptionApi;
private final InvoiceDao invoiceDao;
- private final NonEntityDao nonEntityDao;
+ private final InternalCallContextFactory internalCallContextFactory;
private final InvoiceNotifier invoiceNotifier;
private final GlobalLocker locker;
private final PersistentBus eventBus;
private final Clock clock;
private final OSGIServiceRegistration<InvoicePluginApi> pluginRegistry;
- private final CacheControllerDispatcher controllerDispatcher;
@Inject
public InvoiceDispatcher(final OSGIServiceRegistration<InvoicePluginApi> pluginRegistry,
- final InvoiceGenerator generator, final AccountInternalApi accountApi,
+ final InvoiceGenerator generator,
+ final AccountInternalApi accountApi,
final BillingInternalApi billingApi,
final SubscriptionBaseInternalApi SubscriptionApi,
final InvoiceDao invoiceDao,
- final NonEntityDao nonEntityDao,
+ final InternalCallContextFactory internalCallContextFactory,
final InvoiceNotifier invoiceNotifier,
final GlobalLocker locker,
final PersistentBus eventBus,
- final Clock clock, final CacheControllerDispatcher controllerDispatcher) {
+ final Clock clock) {
this.pluginRegistry = pluginRegistry;
this.generator = generator;
this.billingApi = billingApi;
this.subscriptionApi = SubscriptionApi;
this.accountApi = accountApi;
this.invoiceDao = invoiceDao;
- this.nonEntityDao = nonEntityDao;
+ this.internalCallContextFactory = internalCallContextFactory;
this.invoiceNotifier = invoiceNotifier;
this.locker = locker;
this.eventBus = eventBus;
this.clock = clock;
- this.controllerDispatcher = controllerDispatcher;
}
public void processSubscription(final EffectiveSubscriptionInternalEvent transition,
@@ -337,11 +331,11 @@ public class InvoiceDispatcher {
}
private TenantContext buildTenantContext(final InternalTenantContext context) {
- return context.toTenantContext(nonEntityDao.retrieveIdFromObject(context.getTenantRecordId(), ObjectType.TENANT, controllerDispatcher.getCacheController(CacheType.OBJECT_ID)));
+ return internalCallContextFactory.createTenantContext(context);
}
private CallContext buildCallContext(final InternalCallContext context) {
- return context.toCallContext(nonEntityDao.retrieveIdFromObject(context.getTenantRecordId(), ObjectType.TENANT, controllerDispatcher.getCacheController(CacheType.OBJECT_ID)));
+ return internalCallContextFactory.createCallContext(context);
}
private List<InvoicePluginApi> getInvoicePlugins() {
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/notification/DefaultNextBillingDateNotifier.java b/invoice/src/main/java/org/killbill/billing/invoice/notification/DefaultNextBillingDateNotifier.java
index 25e55c1..27db49b 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/notification/DefaultNextBillingDateNotifier.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/notification/DefaultNextBillingDateNotifier.java
@@ -19,22 +19,21 @@ package org.killbill.billing.invoice.notification;
import java.util.UUID;
import org.joda.time.DateTime;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.killbill.billing.subscription.api.user.SubscriptionBaseApiException;
-import org.killbill.billing.subscription.api.SubscriptionBase;
import org.killbill.billing.invoice.InvoiceListener;
import org.killbill.billing.invoice.api.DefaultInvoiceService;
+import org.killbill.billing.subscription.api.SubscriptionBase;
+import org.killbill.billing.subscription.api.SubscriptionBaseInternalApi;
+import org.killbill.billing.subscription.api.user.SubscriptionBaseApiException;
+import org.killbill.billing.util.callcontext.InternalCallContextFactory;
+import org.killbill.billing.util.config.InvoiceConfig;
import org.killbill.notificationq.api.NotificationEvent;
import org.killbill.notificationq.api.NotificationQueue;
import org.killbill.notificationq.api.NotificationQueueService;
import org.killbill.notificationq.api.NotificationQueueService.NoSuchNotificationQueue;
import org.killbill.notificationq.api.NotificationQueueService.NotificationQueueAlreadyExists;
import org.killbill.notificationq.api.NotificationQueueService.NotificationQueueHandler;
-import org.killbill.billing.util.callcontext.InternalCallContextFactory;
-import org.killbill.billing.util.config.InvoiceConfig;
-import org.killbill.billing.subscription.api.SubscriptionBaseInternalApi;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import com.google.inject.Inject;
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/notification/DefaultNextBillingDatePoster.java b/invoice/src/main/java/org/killbill/billing/invoice/notification/DefaultNextBillingDatePoster.java
index 58c68ae..d4bd06e 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/notification/DefaultNextBillingDatePoster.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/notification/DefaultNextBillingDatePoster.java
@@ -1,7 +1,9 @@
/*
* Copyright 2010-2013 Ning, Inc.
+ * Copyright 2014-2015 Groupon, Inc
+ * Copyright 2014-2015 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:
*
@@ -20,19 +22,15 @@ import java.io.IOException;
import java.util.UUID;
import org.joda.time.DateTime;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
import org.killbill.billing.callcontext.InternalCallContext;
import org.killbill.billing.invoice.api.DefaultInvoiceService;
+import org.killbill.billing.util.entity.dao.EntitySqlDao;
+import org.killbill.billing.util.entity.dao.EntitySqlDaoWrapperFactory;
import org.killbill.notificationq.api.NotificationQueue;
import org.killbill.notificationq.api.NotificationQueueService;
import org.killbill.notificationq.api.NotificationQueueService.NoSuchNotificationQueue;
-import org.killbill.billing.util.callcontext.CallOrigin;
-import org.killbill.billing.util.callcontext.InternalCallContextFactory;
-import org.killbill.billing.util.callcontext.UserType;
-import org.killbill.billing.util.entity.dao.EntitySqlDao;
-import org.killbill.billing.util.entity.dao.EntitySqlDaoWrapperFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import com.google.inject.Inject;
@@ -41,20 +39,15 @@ public class DefaultNextBillingDatePoster implements NextBillingDatePoster {
private static final Logger log = LoggerFactory.getLogger(DefaultNextBillingDatePoster.class);
private final NotificationQueueService notificationQueueService;
- private final InternalCallContextFactory internalCallContextFactory;
@Inject
- public DefaultNextBillingDatePoster(final NotificationQueueService notificationQueueService,
- final InternalCallContextFactory internalCallContextFactory) {
+ public DefaultNextBillingDatePoster(final NotificationQueueService notificationQueueService) {
this.notificationQueueService = notificationQueueService;
- this.internalCallContextFactory = internalCallContextFactory;
}
@Override
public void insertNextBillingNotificationFromTransaction(final EntitySqlDaoWrapperFactory<EntitySqlDao> entitySqlDaoWrapperFactory, final UUID accountId,
- final UUID subscriptionId, final DateTime futureNotificationTime, final UUID userToken) {
- final InternalCallContext context = createCallContext(accountId, userToken);
-
+ final UUID subscriptionId, final DateTime futureNotificationTime, final InternalCallContext internalCallContext) {
final NotificationQueue nextBillingQueue;
try {
nextBillingQueue = notificationQueueService.getNotificationQueue(DefaultInvoiceService.INVOICE_SERVICE_NAME,
@@ -62,34 +55,12 @@ public class DefaultNextBillingDatePoster implements NextBillingDatePoster {
log.info("Queuing next billing date notification at {} for subscriptionId {}", futureNotificationTime.toString(), subscriptionId.toString());
nextBillingQueue.recordFutureNotificationFromTransaction(entitySqlDaoWrapperFactory.getSqlDao(), futureNotificationTime,
- new NextBillingDateNotificationKey(subscriptionId), context.getUserToken(), context.getAccountRecordId(), context.getTenantRecordId());
- } catch (NoSuchNotificationQueue e) {
+ new NextBillingDateNotificationKey(subscriptionId), internalCallContext.getUserToken(),
+ internalCallContext.getAccountRecordId(), internalCallContext.getTenantRecordId());
+ } catch (final NoSuchNotificationQueue e) {
log.error("Attempting to put items on a non-existent queue (NextBillingDateNotifier).", e);
- } catch (IOException e) {
+ } catch (final IOException e) {
log.error("Failed to serialize notificationKey for subscriptionId {}", subscriptionId);
}
}
-
- @Override
- public void insertNextBillingNotification(final UUID accountId, final UUID subscriptionId, final DateTime futureNotificationTime, final UUID userToken) {
- final InternalCallContext context = createCallContext(accountId, userToken);
-
- final NotificationQueue nextBillingQueue;
- try {
- nextBillingQueue = notificationQueueService.getNotificationQueue(DefaultInvoiceService.INVOICE_SERVICE_NAME,
- DefaultNextBillingDateNotifier.NEXT_BILLING_DATE_NOTIFIER_QUEUE);
- log.info("Queuing next billing date notification at {} for subscriptionId {}", futureNotificationTime.toString(), subscriptionId.toString());
-
- nextBillingQueue.recordFutureNotification(futureNotificationTime,
- new NextBillingDateNotificationKey(subscriptionId), context.getUserToken(), context.getAccountRecordId(), context.getTenantRecordId());
- } catch (NoSuchNotificationQueue e) {
- log.error("Attempting to put items on a non-existent queue (NextBillingDateNotifier).", e);
- } catch (IOException e) {
- log.error("Failed to serialize notificationKey for subscriptionId {}", subscriptionId);
- }
- }
-
- private InternalCallContext createCallContext(final UUID accountId, final UUID userToken) {
- return internalCallContextFactory.createInternalCallContext(accountId, "NextBillingDatePoster", CallOrigin.INTERNAL, UserType.SYSTEM, userToken);
- }
}
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/notification/NextBillingDatePoster.java b/invoice/src/main/java/org/killbill/billing/invoice/notification/NextBillingDatePoster.java
index 5a63e86..30f45ff 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/notification/NextBillingDatePoster.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/notification/NextBillingDatePoster.java
@@ -1,7 +1,9 @@
/*
* Copyright 2010-2013 Ning, Inc.
+ * Copyright 2014-2015 Groupon, Inc
+ * Copyright 2014-2015 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:
*
@@ -19,15 +21,12 @@ package org.killbill.billing.invoice.notification;
import java.util.UUID;
import org.joda.time.DateTime;
-
+import org.killbill.billing.callcontext.InternalCallContext;
import org.killbill.billing.util.entity.dao.EntitySqlDao;
import org.killbill.billing.util.entity.dao.EntitySqlDaoWrapperFactory;
public interface NextBillingDatePoster {
void insertNextBillingNotificationFromTransaction(EntitySqlDaoWrapperFactory<EntitySqlDao> entitySqlDaoWrapperFactory, UUID accountId,
- UUID subscriptionId, DateTime futureNotificationTime, UUID userToken);
-
- void insertNextBillingNotification(UUID accountId,
- UUID subscriptionId, DateTime futureNotificationTime, UUID userToken);
+ UUID subscriptionId, DateTime futureNotificationTime, InternalCallContext internalCallContext);
}
diff --git a/invoice/src/test/java/org/killbill/billing/invoice/generator/TestDefaultInvoiceGenerator.java b/invoice/src/test/java/org/killbill/billing/invoice/generator/TestDefaultInvoiceGenerator.java
index 43bbfec..0343fbc 100644
--- a/invoice/src/test/java/org/killbill/billing/invoice/generator/TestDefaultInvoiceGenerator.java
+++ b/invoice/src/test/java/org/killbill/billing/invoice/generator/TestDefaultInvoiceGenerator.java
@@ -1,7 +1,9 @@
/*
* Copyright 2010-2013 Ning, Inc.
+ * Copyright 2014-2015 Groupon, Inc
+ * Copyright 2014-2015 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:
*
@@ -112,7 +114,7 @@ public class TestDefaultInvoiceGenerator extends InvoiceTestSuiteNoDB {
return true;
}
};
- this.generator = new DefaultInvoiceGenerator(clock, null, invoiceConfig, null, controllerDispatcher);
+ this.generator = new DefaultInvoiceGenerator(clock, null, invoiceConfig, internalCallContextFactory);
}
@Test(groups = "fast")
diff --git a/invoice/src/test/java/org/killbill/billing/invoice/TestInvoiceDispatcher.java b/invoice/src/test/java/org/killbill/billing/invoice/TestInvoiceDispatcher.java
index 83c6bc6..1b2a4d0 100644
--- a/invoice/src/test/java/org/killbill/billing/invoice/TestInvoiceDispatcher.java
+++ b/invoice/src/test/java/org/killbill/billing/invoice/TestInvoiceDispatcher.java
@@ -1,7 +1,7 @@
/*
* Copyright 2010-2013 Ning, Inc.
- * Copyright 2014 Groupon, Inc
- * Copyright 2014 The Billing Project, LLC
+ * Copyright 2014-2015 Groupon, Inc
+ * Copyright 2014-2015 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
@@ -39,7 +39,6 @@ import org.killbill.billing.catalog.api.Currency;
import org.killbill.billing.catalog.api.PhaseType;
import org.killbill.billing.catalog.api.Plan;
import org.killbill.billing.catalog.api.PlanPhase;
-import org.killbill.billing.entitlement.api.SubscriptionEventType;
import org.killbill.billing.invoice.TestInvoiceHelper.DryRunFutureDateArguments;
import org.killbill.billing.invoice.api.DryRunArguments;
import org.killbill.billing.invoice.api.Invoice;
@@ -55,7 +54,6 @@ import org.killbill.billing.subscription.api.SubscriptionBase;
import org.killbill.billing.subscription.api.SubscriptionBaseTransitionType;
import org.killbill.billing.util.timezone.DateAndTimeZoneContext;
import org.killbill.clock.ClockMock;
-import org.mockito.Mock;
import org.mockito.Mockito;
import org.testng.Assert;
import org.testng.annotations.BeforeMethod;
@@ -90,14 +88,14 @@ public class TestInvoiceDispatcher extends InvoiceTestSuiteWithEmbeddedDB {
fixedPrice, BigDecimal.ONE, currency, BillingPeriod.MONTHLY, 1,
BillingMode.IN_ADVANCE, "", 1L, SubscriptionBaseTransitionType.CREATE));
- Mockito.when(billingApi.getBillingEventsForAccountAndUpdateAccountBCD(Mockito.<UUID>any(), Mockito.<DryRunArguments>any(), Mockito.<InternalCallContext>any())).thenReturn(events);
+ Mockito.when(billingApi.getBillingEventsForAccountAndUpdateAccountBCD(Mockito.<UUID>any(), Mockito.<DryRunArguments>any(), Mockito.<InternalCallContext>any())).thenReturn(events);
final DateTime target = new DateTime();
final InvoiceNotifier invoiceNotifier = new NullInvoiceNotifier();
final InvoiceDispatcher dispatcher = new InvoiceDispatcher(pluginRegistry, generator, accountApi, billingApi, subscriptionApi, invoiceDao,
- nonEntityDao, invoiceNotifier, locker, busService.getBus(),
- clock, controllerDispatcher);
+ internalCallContextFactory, invoiceNotifier, locker, busService.getBus(),
+ clock);
Invoice invoice = dispatcher.processAccount(accountId, target, new DryRunFutureDateArguments(), context);
Assert.assertNotNull(invoice);
@@ -149,8 +147,8 @@ public class TestInvoiceDispatcher extends InvoiceTestSuiteWithEmbeddedDB {
Mockito.when(billingApi.getBillingEventsForAccountAndUpdateAccountBCD(Mockito.<UUID>any(), Mockito.<DryRunArguments>any(), Mockito.<InternalCallContext>any())).thenReturn(events);
final InvoiceNotifier invoiceNotifier = new NullInvoiceNotifier();
final InvoiceDispatcher dispatcher = new InvoiceDispatcher(pluginRegistry, generator, accountApi, billingApi, subscriptionApi, invoiceDao,
- nonEntityDao, invoiceNotifier, locker, busService.getBus(),
- clock, controllerDispatcher);
+ internalCallContextFactory, invoiceNotifier, locker, busService.getBus(),
+ clock);
final Invoice invoice = dispatcher.processAccount(account.getId(), new DateTime("2012-07-30T00:00:00.000Z"), null, context);
Assert.assertNotNull(invoice);
@@ -207,8 +205,8 @@ public class TestInvoiceDispatcher extends InvoiceTestSuiteWithEmbeddedDB {
final InvoiceNotifier invoiceNotifier = new NullInvoiceNotifier();
final InvoiceDispatcher dispatcher = new InvoiceDispatcher(pluginRegistry, generator, accountApi, billingApi, subscriptionApi, invoiceDao,
- nonEntityDao, invoiceNotifier, locker, busService.getBus(),
- clock, controllerDispatcher);
+ internalCallContextFactory, invoiceNotifier, locker, busService.getBus(),
+ clock);
final Map<UUID, List<DateTime>> result = dispatcher.createNextFutureNotificationDate(Collections.singletonList(item), null, dateAndTimeZoneContext);
diff --git a/invoice/src/test/java/org/killbill/billing/invoice/TestInvoiceHelper.java b/invoice/src/test/java/org/killbill/billing/invoice/TestInvoiceHelper.java
index 407e59f..4fc02ca 100644
--- a/invoice/src/test/java/org/killbill/billing/invoice/TestInvoiceHelper.java
+++ b/invoice/src/test/java/org/killbill/billing/invoice/TestInvoiceHelper.java
@@ -1,7 +1,7 @@
/*
* Copyright 2010-2013 Ning, Inc.
- * Copyright 2014 Groupon, Inc
- * Copyright 2014 The Billing Project, LLC
+ * Copyright 2014-2015 Groupon, Inc
+ * Copyright 2014-2015 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
@@ -74,11 +74,9 @@ import org.killbill.billing.subscription.api.SubscriptionBase;
import org.killbill.billing.subscription.api.SubscriptionBaseInternalApi;
import org.killbill.billing.subscription.api.SubscriptionBaseTransitionType;
import org.killbill.billing.subscription.api.user.SubscriptionBaseApiException;
-import org.killbill.billing.util.cache.CacheControllerDispatcher;
import org.killbill.billing.util.callcontext.CallContext;
import org.killbill.billing.util.callcontext.InternalCallContextFactory;
import org.killbill.billing.util.currency.KillBillMoney;
-import org.killbill.billing.util.dao.NonEntityDao;
import org.killbill.clock.Clock;
import org.killbill.commons.locker.GlobalLocker;
import org.mockito.Mockito;
@@ -153,9 +151,7 @@ public class TestInvoiceHelper {
private final GlobalLocker locker;
private final Clock clock;
private final InternalCallContext internalCallContext;
- private final NonEntityDao nonEntityDao;
private final InternalCallContextFactory internalCallContextFactory;
- private final CacheControllerDispatcher cacheControllerDispatcher;
// Low level SqlDao used by the tests to directly insert rows
private final InvoicePaymentSqlDao invoicePaymentSqlDao;
@@ -164,8 +160,8 @@ public class TestInvoiceHelper {
@Inject
public TestInvoiceHelper(final OSGIServiceRegistration<InvoicePluginApi> pluginRegistry, final InvoiceGenerator generator, final IDBI dbi,
final BillingInternalApi billingApi, final AccountInternalApi accountApi, final AccountUserApi accountUserApi, final SubscriptionBaseInternalApi subscriptionApi, final BusService busService,
- final InvoiceDao invoiceDao, final GlobalLocker locker, final Clock clock, final NonEntityDao nonEntityDao, final InternalCallContext internalCallContext,
- final InternalCallContextFactory internalCallContextFactory, final CacheControllerDispatcher cacheControllerDispatcher) {
+ final InvoiceDao invoiceDao, final GlobalLocker locker, final Clock clock, final InternalCallContext internalCallContext,
+ final InternalCallContextFactory internalCallContextFactory) {
this.pluginRegistry = pluginRegistry;
this.generator = generator;
this.billingApi = billingApi;
@@ -176,12 +172,10 @@ public class TestInvoiceHelper {
this.invoiceDao = invoiceDao;
this.locker = locker;
this.clock = clock;
- this.nonEntityDao = nonEntityDao;
this.internalCallContext = internalCallContext;
this.internalCallContextFactory = internalCallContextFactory;
this.invoiceItemSqlDao = dbi.onDemand(InvoiceItemSqlDao.class);
this.invoicePaymentSqlDao = dbi.onDemand(InvoicePaymentSqlDao.class);
- this.cacheControllerDispatcher = cacheControllerDispatcher;
}
public UUID generateRegularInvoice(final Account account, final DateTime targetDate, final CallContext callContext) throws Exception {
@@ -202,8 +196,8 @@ public class TestInvoiceHelper {
final InvoiceNotifier invoiceNotifier = new NullInvoiceNotifier();
final InvoiceDispatcher dispatcher = new InvoiceDispatcher(pluginRegistry, generator, accountApi, billingApi, subscriptionApi,
- invoiceDao, nonEntityDao, invoiceNotifier, locker, busService.getBus(),
- clock, cacheControllerDispatcher);
+ invoiceDao, internalCallContextFactory, invoiceNotifier, locker, busService.getBus(),
+ clock);
Invoice invoice = dispatcher.processAccount(account.getId(), targetDate, new DryRunFutureDateArguments(), internalCallContext);
Assert.assertNotNull(invoice);
@@ -223,7 +217,7 @@ public class TestInvoiceHelper {
}
public SubscriptionBase createSubscription() throws SubscriptionBaseApiException {
- UUID uuid = UUID.randomUUID();
+ final UUID uuid = UUID.randomUUID();
final SubscriptionBase subscription = Mockito.mock(SubscriptionBase.class);
Mockito.when(subscription.getId()).thenReturn(uuid);
Mockito.when(subscriptionApi.getSubscriptionFromId(Mockito.<UUID>any(), Mockito.<InternalTenantContext>any())).thenReturn(subscription);
@@ -291,7 +285,7 @@ public class TestInvoiceHelper {
public void createPayment(final InvoicePayment invoicePayment, final InternalCallContext internalCallContext) {
try {
invoicePaymentSqlDao.create(new InvoicePaymentModelDao(invoicePayment), internalCallContext);
- } catch (EntityPersistenceException e) {
+ } catch (final EntityPersistenceException e) {
Assert.fail(e.getMessage());
}
}
@@ -424,21 +418,27 @@ public class TestInvoiceHelper {
}
};
}
+
public static class DryRunFutureDateArguments implements DryRunArguments {
+
public DryRunFutureDateArguments() {
}
+
@Override
public PlanPhaseSpecifier getPlanPhaseSpecifier() {
return null;
}
+
@Override
public SubscriptionEventType getAction() {
return null;
}
+
@Override
public UUID getSubscriptionId() {
return null;
}
+
@Override
public DateTime getEffectiveDate() {
return null;
diff --git a/overdue/src/main/java/org/killbill/billing/overdue/applicator/OverdueStateApplicator.java b/overdue/src/main/java/org/killbill/billing/overdue/applicator/OverdueStateApplicator.java
index 7a5735a..d59430a 100644
--- a/overdue/src/main/java/org/killbill/billing/overdue/applicator/OverdueStateApplicator.java
+++ b/overdue/src/main/java/org/killbill/billing/overdue/applicator/OverdueStateApplicator.java
@@ -1,7 +1,9 @@
/*
* Copyright 2010-2013 Ning, Inc.
+ * Copyright 2014-2015 Groupon, Inc
+ * Copyright 2014-2015 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:
*
@@ -57,9 +59,8 @@ import org.killbill.billing.overdue.notification.OverdueCheckNotifier;
import org.killbill.billing.overdue.notification.OverduePoster;
import org.killbill.billing.tag.TagInternalApi;
import org.killbill.billing.util.api.TagApiException;
-import org.killbill.billing.util.cache.Cachable.CacheType;
-import org.killbill.billing.util.cache.CacheControllerDispatcher;
-import org.killbill.billing.util.dao.NonEntityDao;
+import org.killbill.billing.util.callcontext.CallContext;
+import org.killbill.billing.util.callcontext.InternalCallContextFactory;
import org.killbill.billing.util.email.DefaultEmailSender;
import org.killbill.billing.util.email.EmailApiException;
import org.killbill.billing.util.email.EmailConfig;
@@ -90,8 +91,7 @@ public class OverdueStateApplicator {
private final OverdueEmailGenerator overdueEmailGenerator;
private final TagInternalApi tagApi;
private final EmailSender emailSender;
- private final NonEntityDao nonEntityDao;
- private final CacheControllerDispatcher controllerDispatcher;
+ private final InternalCallContextFactory internalCallContextFactory;
@Inject
public OverdueStateApplicator(final BlockingInternalApi accessApi,
@@ -102,9 +102,8 @@ public class OverdueStateApplicator {
final OverdueEmailGenerator overdueEmailGenerator,
final EmailConfig config,
final PersistentBus bus,
- final NonEntityDao nonEntityDao,
final TagInternalApi tagApi,
- final CacheControllerDispatcher controllerDispatcher) {
+ final InternalCallContextFactory internalCallContextFactory) {
this.blockingApi = accessApi;
this.accountApi = accountApi;
@@ -113,10 +112,9 @@ public class OverdueStateApplicator {
this.checkPoster = checkPoster;
this.overdueEmailGenerator = overdueEmailGenerator;
this.tagApi = tagApi;
- this.nonEntityDao = nonEntityDao;
+ this.internalCallContextFactory = internalCallContextFactory;
this.emailSender = new DefaultEmailSender(config);
this.bus = bus;
- this.controllerDispatcher = controllerDispatcher;
}
public void apply(final OverdueStateSet overdueStateSet, final BillingState billingState,
@@ -165,7 +163,7 @@ public class OverdueStateApplicator {
// 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(account, nextOverdueState, context);
- } catch (OverdueApiException e) {
+ } catch (final OverdueApiException e) {
if (e.getCode() != ErrorCode.OVERDUE_NO_REEVALUATION_INTERVAL.getCode()) {
throw new OverdueException(e);
}
@@ -173,7 +171,7 @@ public class OverdueStateApplicator {
try {
bus.post(createOverdueEvent(account, previousOverdueState.getName(), nextOverdueState.getName(), isBlockBillingTransition(previousOverdueState, nextOverdueState),
isUnblockBillingTransition(previousOverdueState, nextOverdueState), context));
- } catch (Exception e) {
+ } catch (final Exception e) {
log.error("Error posting overdue change event to bus", e);
}
}
@@ -197,14 +195,14 @@ public class OverdueStateApplicator {
try {
avoid_extra_credit_by_toggling_AUTO_INVOICE_OFF(account, previousOverdueState, clearState, context);
- } catch (OverdueApiException e) {
+ } catch (final OverdueApiException e) {
throw new OverdueException(e);
}
try {
bus.post(createOverdueEvent(account, previousOverdueState.getName(), clearState.getName(), isBlockBillingTransition(previousOverdueState, clearState),
isUnblockBillingTransition(previousOverdueState, clearState), context));
- } catch (Exception e) {
+ } catch (final Exception e) {
log.error("Error posting overdue change event to bus", e);
}
}
@@ -226,7 +224,7 @@ public class OverdueStateApplicator {
blockBilling(nextOverdueState),
clock.getUTCNow()),
context);
- } catch (Exception e) {
+ } catch (final Exception e) {
throw new OverdueException(e, ErrorCode.OVERDUE_CAT_ERROR_ENCOUNTERED, blockable.getId(), blockable.getClass().getName());
}
}
@@ -234,7 +232,7 @@ public class OverdueStateApplicator {
private void set_AUTO_INVOICE_OFF_on_blockedBilling(final UUID accountId, final InternalCallContext context) throws OverdueApiException {
try {
tagApi.addTag(accountId, ObjectType.ACCOUNT, ControlTagType.AUTO_INVOICING_OFF.getId(), context);
- } catch (TagApiException e) {
+ } catch (final TagApiException e) {
throw new OverdueApiException(e);
}
}
@@ -242,7 +240,7 @@ public class OverdueStateApplicator {
private void remove_AUTO_INVOICE_OFF_on_clear(final UUID accountId, final InternalCallContext context) throws OverdueApiException {
try {
tagApi.removeTag(accountId, ObjectType.ACCOUNT, ControlTagType.AUTO_INVOICING_OFF.getId(), context);
- } catch (TagApiException e) {
+ } catch (final TagApiException e) {
if (e.getCode() != ErrorCode.TAG_DOES_NOT_EXIST.getCode()) {
throw new OverdueApiException(e);
}
@@ -283,6 +281,8 @@ public class OverdueStateApplicator {
if (nextOverdueState.getOverdueCancellationPolicy() == OverdueCancellationPolicy.NONE) {
return;
}
+
+ final CallContext callContext = internalCallContextFactory.createCallContext(context);
try {
final BillingActionPolicy actionPolicy;
switch (nextOverdueState.getOverdueCancellationPolicy()) {
@@ -296,27 +296,25 @@ public class OverdueStateApplicator {
throw new IllegalStateException("Unexpected OverdueCancellationPolicy " + nextOverdueState.getOverdueCancellationPolicy());
}
final List<Entitlement> toBeCancelled = new LinkedList<Entitlement>();
- computeEntitlementsToCancel(account, toBeCancelled, context);
+ computeEntitlementsToCancel(account, toBeCancelled, callContext);
- final UUID tenantId = nonEntityDao.retrieveIdFromObject(context.getTenantRecordId(), ObjectType.TENANT, controllerDispatcher.getCacheController(CacheType.OBJECT_ID));
for (final Entitlement cur : toBeCancelled) {
try {
- cur.cancelEntitlementWithDateOverrideBillingPolicy(new LocalDate(clock.getUTCNow(), account.getTimeZone()), actionPolicy, context.toCallContext(tenantId));
- } catch (EntitlementApiException e) {
+ cur.cancelEntitlementWithDateOverrideBillingPolicy(new LocalDate(clock.getUTCNow(), account.getTimeZone()), actionPolicy, callContext);
+ } catch (final EntitlementApiException e) {
// If subscription has already been cancelled, there is nothing to do so we can ignore
if (e.getCode() != ErrorCode.SUB_CANCEL_BAD_STATE.getCode()) {
throw new OverdueException(e);
}
}
}
- } catch (EntitlementApiException e) {
+ } catch (final EntitlementApiException e) {
throw new OverdueException(e);
}
}
- private void computeEntitlementsToCancel(final Account account, final List<Entitlement> result, final InternalTenantContext context) throws EntitlementApiException {
- final UUID tenantId = nonEntityDao.retrieveIdFromObject(context.getTenantRecordId(), ObjectType.TENANT, controllerDispatcher.getCacheController(CacheType.OBJECT_ID));
- final List<Entitlement> allEntitlementsForAccountId = entitlementApi.getAllEntitlementsForAccountId(account.getId(), context.toTenantContext(tenantId));
+ private void computeEntitlementsToCancel(final Account account, final List<Entitlement> result, final CallContext context) throws EntitlementApiException {
+ final List<Entitlement> allEntitlementsForAccountId = entitlementApi.getAllEntitlementsForAccountId(account.getId(), context);
// Entitlement is smart enough and will cancel the associated add-ons. See also discussion in https://github.com/killbill/killbill/issues/94
final Collection<Entitlement> allEntitlementsButAddonsForAccountId = Collections2.<Entitlement>filter(allEntitlementsForAccountId,
new Predicate<Entitlement>() {
@@ -352,11 +350,11 @@ public class OverdueStateApplicator {
} else {
emailSender.sendPlainTextEmail(to, cc, subject, emailBody);
}
- } catch (IOException e) {
+ } catch (final IOException e) {
log.warn(String.format("Unable to generate or send overdue notification email for account %s and overdueable %s", account.getId(), account.getId()), e);
- } catch (EmailApiException e) {
+ } catch (final EmailApiException e) {
log.warn(String.format("Unable to send overdue notification email for account %s and overdueable %s", account.getId(), account.getId()), e);
- } catch (MustacheException e) {
+ } catch (final MustacheException e) {
log.warn(String.format("Unable to generate overdue notification email for account %s and overdueable %s", account.getId(), account.getId()), e);
}
}
@@ -370,13 +368,13 @@ public class OverdueStateApplicator {
final UUID accountId = accountApi.getByRecordId(context.getAccountRecordId(), context);
final List<Tag> accountTags = tagApi.getTags(accountId, ObjectType.ACCOUNT, context);
- for (Tag cur : accountTags) {
+ for (final Tag cur : accountTags) {
if (cur.getTagDefinitionId().equals(ControlTagType.OVERDUE_ENFORCEMENT_OFF.getId())) {
return true;
}
}
return false;
- } catch (AccountApiException e) {
+ } catch (final AccountApiException e) {
throw new OverdueException(e);
}
}
diff --git a/payment/src/main/java/org/killbill/billing/payment/bus/InvoiceHandler.java b/payment/src/main/java/org/killbill/billing/payment/bus/InvoiceHandler.java
index 80c1770..22dd22c 100644
--- a/payment/src/main/java/org/killbill/billing/payment/bus/InvoiceHandler.java
+++ b/payment/src/main/java/org/killbill/billing/payment/bus/InvoiceHandler.java
@@ -1,7 +1,7 @@
/*
* Copyright 2010-2013 Ning, Inc.
- * Copyright 2014 Groupon, Inc
- * Copyright 2014 The Billing Project, LLC
+ * Copyright 2014-2015 Groupon, Inc
+ * Copyright 2014-2015 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,7 +25,6 @@ import java.util.List;
import java.util.UUID;
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;
@@ -35,14 +34,11 @@ import org.killbill.billing.payment.api.PaymentApiException;
import org.killbill.billing.payment.api.PluginProperty;
import org.killbill.billing.payment.core.PluginRoutingPaymentProcessor;
import org.killbill.billing.payment.invoice.InvoicePaymentRoutingPluginApi;
-import org.killbill.billing.util.cache.Cachable.CacheType;
-import org.killbill.billing.util.cache.CacheControllerDispatcher;
import org.killbill.billing.util.callcontext.CallContext;
import org.killbill.billing.util.callcontext.CallOrigin;
import org.killbill.billing.util.callcontext.InternalCallContextFactory;
import org.killbill.billing.util.callcontext.UserType;
import org.killbill.billing.util.config.PaymentConfig;
-import org.killbill.billing.util.dao.NonEntityDao;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -54,8 +50,6 @@ public class InvoiceHandler {
private final AccountInternalApi accountApi;
private final InternalCallContextFactory internalCallContextFactory;
private final PluginRoutingPaymentProcessor pluginRoutingPaymentProcessor;
- private final NonEntityDao nonEntityDao;
- private final CacheControllerDispatcher controllerDispatcher;
private final PaymentConfig paymentConfig;
private static final Logger log = LoggerFactory.getLogger(InvoiceHandler.class);
@@ -64,20 +58,15 @@ public class InvoiceHandler {
public InvoiceHandler(final PaymentConfig paymentConfig,
final AccountInternalApi accountApi,
final PluginRoutingPaymentProcessor pluginRoutingPaymentProcessor,
- final NonEntityDao nonEntityDao,
- final InternalCallContextFactory internalCallContextFactory,
- final CacheControllerDispatcher controllerDispatcher) {
+ final InternalCallContextFactory internalCallContextFactory) {
this.paymentConfig = paymentConfig;
this.accountApi = accountApi;
this.internalCallContextFactory = internalCallContextFactory;
this.pluginRoutingPaymentProcessor = pluginRoutingPaymentProcessor;
- this.nonEntityDao = nonEntityDao;
- this.controllerDispatcher = controllerDispatcher;
}
@Subscribe
public void processInvoiceEvent(final InvoiceCreationInternalEvent event) {
-
log.info("Received invoice creation notification for account {} and invoice {}",
event.getAccountId(), event.getInvoiceId());
@@ -90,7 +79,7 @@ public class InvoiceHandler {
final PluginProperty prop1 = new PluginProperty(InvoicePaymentRoutingPluginApi.PROP_IPCD_INVOICE_ID, event.getInvoiceId().toString(), false);
properties.add(prop1);
- final CallContext callContext = internalContext.toCallContext(nonEntityDao.retrieveIdFromObject(internalContext.getTenantRecordId(), ObjectType.TENANT, controllerDispatcher.getCacheController(CacheType.OBJECT_ID)));
+ final CallContext callContext = internalCallContextFactory.createCallContext(internalContext);
final BigDecimal amountToBePaid = null; // We let the plugin compute how much should be paid
final List<String> paymentControlPluginNames = paymentConfig.getPaymentControlPluginNames() != null ? new LinkedList<String>(paymentConfig.getPaymentControlPluginNames()) : new LinkedList<String>();
diff --git a/payment/src/main/java/org/killbill/billing/payment/core/janitor/AttemptCompletionTask.java b/payment/src/main/java/org/killbill/billing/payment/core/janitor/AttemptCompletionTask.java
index fcf5796..95fe5bc 100644
--- a/payment/src/main/java/org/killbill/billing/payment/core/janitor/AttemptCompletionTask.java
+++ b/payment/src/main/java/org/killbill/billing/payment/core/janitor/AttemptCompletionTask.java
@@ -1,6 +1,6 @@
/*
- * Copyright 2014 Groupon, Inc
- * Copyright 2014 The Billing Project, LLC
+ * Copyright 2014-2015 Groupon, Inc
+ * Copyright 2014-2015 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
@@ -19,7 +19,6 @@ package org.killbill.billing.payment.core.janitor;
import java.util.List;
-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;
@@ -38,11 +37,9 @@ import org.killbill.billing.payment.dao.PaymentTransactionModelDao;
import org.killbill.billing.payment.dao.PluginPropertySerializer;
import org.killbill.billing.payment.dao.PluginPropertySerializer.PluginPropertySerializerException;
import org.killbill.billing.payment.plugin.api.PaymentPluginApi;
-import org.killbill.billing.util.cache.CacheControllerDispatcher;
import org.killbill.billing.util.callcontext.CallContext;
import org.killbill.billing.util.callcontext.InternalCallContextFactory;
import org.killbill.billing.util.config.PaymentConfig;
-import org.killbill.billing.util.dao.NonEntityDao;
import org.killbill.clock.Clock;
import com.google.common.base.Predicate;
@@ -57,10 +54,10 @@ import com.google.common.collect.Iterables;
final class AttemptCompletionTask extends CompletionTaskBase<PaymentAttemptModelDao> {
public AttemptCompletionTask(final Janitor janitor, final InternalCallContextFactory internalCallContextFactory, final PaymentConfig paymentConfig,
- final NonEntityDao nonEntityDao, final PaymentDao paymentDao, final Clock clock, final PaymentStateMachineHelper paymentStateMachineHelper,
- final RetryStateMachineHelper retrySMHelper, final CacheControllerDispatcher controllerDispatcher, final AccountInternalApi accountInternalApi,
+ final PaymentDao paymentDao, final Clock clock, final PaymentStateMachineHelper paymentStateMachineHelper,
+ final RetryStateMachineHelper retrySMHelper, final AccountInternalApi accountInternalApi,
final PluginRoutingPaymentAutomatonRunner pluginControlledPaymentAutomatonRunner, final OSGIServiceRegistration<PaymentPluginApi> pluginRegistry) {
- super(janitor, internalCallContextFactory, paymentConfig, nonEntityDao, paymentDao, clock, paymentStateMachineHelper, retrySMHelper, controllerDispatcher, accountInternalApi, pluginControlledPaymentAutomatonRunner, pluginRegistry);
+ super(janitor, internalCallContextFactory, paymentConfig, paymentDao, clock, paymentStateMachineHelper, retrySMHelper, accountInternalApi, pluginControlledPaymentAutomatonRunner, pluginRegistry);
}
@Override
@@ -72,7 +69,7 @@ final class AttemptCompletionTask extends CompletionTaskBase<PaymentAttemptModel
@Override
public void doIteration(final PaymentAttemptModelDao attempt) {
- final InternalTenantContext tenantContext = internalCallContextFactory.createInternalTenantContext(attempt.getAccountId(), attempt.getId(), ObjectType.PAYMENT_ATTEMPT);
+ final InternalTenantContext tenantContext = internalCallContextFactory.createInternalTenantContext(attempt.getTenantRecordId(), attempt.getAccountRecordId());
final CallContext callContext = createCallContext("AttemptCompletionJanitorTask", tenantContext);
final InternalCallContext internalCallContext = internalCallContextFactory.createInternalCallContext(attempt.getAccountId(), callContext);
@@ -117,11 +114,11 @@ final class AttemptCompletionTask extends CompletionTaskBase<PaymentAttemptModel
// to the PaymentControlPluginApi plugin and transition the state.
//
pluginControlledPaymentAutomatonRunner.completeRun(paymentStateContext);
- } catch (AccountApiException e) {
+ } catch (final AccountApiException e) {
log.warn("Janitor AttemptCompletionTask failed to complete payment attempt " + attempt.getId(), e);
- } catch (PluginPropertySerializerException e) {
+ } catch (final PluginPropertySerializerException e) {
log.warn("Janitor AttemptCompletionTask failed to complete payment attempt " + attempt.getId(), e);
- } catch (PaymentApiException e) {
+ } catch (final PaymentApiException e) {
log.warn("Janitor AttemptCompletionTask failed to complete payment attempt " + attempt.getId(), e);
}
}
diff --git a/payment/src/main/java/org/killbill/billing/payment/core/janitor/CompletionTaskBase.java b/payment/src/main/java/org/killbill/billing/payment/core/janitor/CompletionTaskBase.java
index ef84a79..623ab72 100644
--- a/payment/src/main/java/org/killbill/billing/payment/core/janitor/CompletionTaskBase.java
+++ b/payment/src/main/java/org/killbill/billing/payment/core/janitor/CompletionTaskBase.java
@@ -1,6 +1,6 @@
/*
- * Copyright 2014 Groupon, Inc
- * Copyright 2014 The Billing Project, LLC
+ * Copyright 2014-2015 Groupon, Inc
+ * Copyright 2014-2015 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
@@ -21,7 +21,6 @@ import java.util.List;
import java.util.UUID;
import org.joda.time.DateTime;
-import org.killbill.billing.ObjectType;
import org.killbill.billing.account.api.AccountInternalApi;
import org.killbill.billing.callcontext.DefaultCallContext;
import org.killbill.billing.callcontext.InternalCallContext;
@@ -32,14 +31,12 @@ import org.killbill.billing.payment.core.sm.PluginRoutingPaymentAutomatonRunner;
import org.killbill.billing.payment.core.sm.RetryStateMachineHelper;
import org.killbill.billing.payment.dao.PaymentDao;
import org.killbill.billing.payment.plugin.api.PaymentPluginApi;
-import org.killbill.billing.util.cache.Cachable.CacheType;
-import org.killbill.billing.util.cache.CacheControllerDispatcher;
import org.killbill.billing.util.callcontext.CallContext;
import org.killbill.billing.util.callcontext.CallOrigin;
import org.killbill.billing.util.callcontext.InternalCallContextFactory;
+import org.killbill.billing.util.callcontext.TenantContext;
import org.killbill.billing.util.callcontext.UserType;
import org.killbill.billing.util.config.PaymentConfig;
-import org.killbill.billing.util.dao.NonEntityDao;
import org.killbill.clock.Clock;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -48,7 +45,7 @@ abstract class CompletionTaskBase<T> implements Runnable {
protected Logger log = LoggerFactory.getLogger(CompletionTaskBase.class);
- private Janitor janitor;
+ private final Janitor janitor;
private final String taskName;
protected final PaymentConfig paymentConfig;
@@ -56,28 +53,23 @@ abstract class CompletionTaskBase<T> implements Runnable {
protected final PaymentDao paymentDao;
protected final InternalCallContext completionTaskCallContext;
protected final InternalCallContextFactory internalCallContextFactory;
- protected final NonEntityDao nonEntityDao;
protected final PaymentStateMachineHelper paymentStateMachineHelper;
protected final RetryStateMachineHelper retrySMHelper;
- protected final CacheControllerDispatcher controllerDispatcher;
protected final AccountInternalApi accountInternalApi;
protected final PluginRoutingPaymentAutomatonRunner pluginControlledPaymentAutomatonRunner;
protected final OSGIServiceRegistration<PaymentPluginApi> pluginRegistry;
-
public CompletionTaskBase(final Janitor janitor, final InternalCallContextFactory internalCallContextFactory, final PaymentConfig paymentConfig,
- final NonEntityDao nonEntityDao, final PaymentDao paymentDao, final Clock clock, final PaymentStateMachineHelper paymentStateMachineHelper,
- final RetryStateMachineHelper retrySMHelper, final CacheControllerDispatcher controllerDispatcher, final AccountInternalApi accountInternalApi,
+ final PaymentDao paymentDao, final Clock clock, final PaymentStateMachineHelper paymentStateMachineHelper,
+ final RetryStateMachineHelper retrySMHelper, final AccountInternalApi accountInternalApi,
final PluginRoutingPaymentAutomatonRunner pluginControlledPaymentAutomatonRunner, final OSGIServiceRegistration<PaymentPluginApi> pluginRegistry) {
this.janitor = janitor;
this.internalCallContextFactory = internalCallContextFactory;
this.paymentConfig = paymentConfig;
- this.nonEntityDao = nonEntityDao;
this.paymentDao = paymentDao;
this.clock = clock;
this.paymentStateMachineHelper = paymentStateMachineHelper;
this.retrySMHelper = retrySMHelper;
- this.controllerDispatcher = controllerDispatcher;
this.accountInternalApi = accountInternalApi;
this.pluginControlledPaymentAutomatonRunner = pluginControlledPaymentAutomatonRunner;
this.pluginRegistry = pluginRegistry;
@@ -94,14 +86,14 @@ abstract class CompletionTaskBase<T> implements Runnable {
return;
}
final List<T> items = getItemsForIteration();
- for (T item : items) {
+ for (final T item : items) {
if (janitor.isStopped()) {
log.info("Janitor Task " + taskName + " was requested to stop");
return;
}
try {
doIteration(item);
- } catch(IllegalStateException e) {
+ } catch (final IllegalStateException e) {
log.warn(e.getMessage());
}
}
@@ -111,13 +103,12 @@ abstract class CompletionTaskBase<T> implements Runnable {
public abstract void doIteration(final T item);
- protected CallContext createCallContext(final String taskName, final InternalTenantContext tenantContext) {
- final UUID tenantId = nonEntityDao.retrieveIdFromObject(tenantContext.getTenantRecordId(), ObjectType.TENANT, controllerDispatcher.getCacheController(CacheType.OBJECT_ID));
- final CallContext callContext = new DefaultCallContext(tenantId, taskName, CallOrigin.INTERNAL, UserType.SYSTEM, UUID.randomUUID(), clock);
+ protected CallContext createCallContext(final String taskName, final InternalTenantContext internalTenantContext) {
+ final TenantContext tenantContext = internalCallContextFactory.createTenantContext(internalTenantContext);
+ final CallContext callContext = new DefaultCallContext(tenantContext.getTenantId(), taskName, CallOrigin.INTERNAL, UserType.SYSTEM, UUID.randomUUID(), clock);
return callContext;
}
-
protected DateTime getCreatedDateBefore() {
final long delayBeforeNowMs = paymentConfig.getJanitorPendingCleanupTime().getMillis();
return clock.getUTCNow().minusMillis((int) delayBeforeNowMs);
diff --git a/payment/src/main/java/org/killbill/billing/payment/core/janitor/ErroredPaymentTask.java b/payment/src/main/java/org/killbill/billing/payment/core/janitor/ErroredPaymentTask.java
index 44c098b..922e369 100644
--- a/payment/src/main/java/org/killbill/billing/payment/core/janitor/ErroredPaymentTask.java
+++ b/payment/src/main/java/org/killbill/billing/payment/core/janitor/ErroredPaymentTask.java
@@ -1,6 +1,6 @@
/*
- * Copyright 2014 Groupon, Inc
- * Copyright 2014 The Billing Project, LLC
+ * Copyright 2014-2015 Groupon, Inc
+ * Copyright 2014-2015 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
@@ -23,7 +23,6 @@ import java.util.List;
import javax.annotation.Nullable;
import org.joda.time.DateTime;
-import org.killbill.billing.ObjectType;
import org.killbill.billing.account.api.AccountInternalApi;
import org.killbill.billing.callcontext.InternalCallContext;
import org.killbill.billing.callcontext.InternalTenantContext;
@@ -42,11 +41,9 @@ import org.killbill.billing.payment.dao.PaymentTransactionModelDao;
import org.killbill.billing.payment.plugin.api.PaymentPluginApi;
import org.killbill.billing.payment.plugin.api.PaymentPluginApiException;
import org.killbill.billing.payment.plugin.api.PaymentTransactionInfoPlugin;
-import org.killbill.billing.util.cache.CacheControllerDispatcher;
import org.killbill.billing.util.callcontext.CallContext;
import org.killbill.billing.util.callcontext.InternalCallContextFactory;
import org.killbill.billing.util.config.PaymentConfig;
-import org.killbill.billing.util.dao.NonEntityDao;
import org.killbill.clock.Clock;
import com.google.common.base.Preconditions;
@@ -62,16 +59,16 @@ public class ErroredPaymentTask extends CompletionTaskBase<PaymentModelDao> {
private final int MAX_ITEMS_PER_LOOP = 100; // Limit of items per iteration
public ErroredPaymentTask(final Janitor janitor, final InternalCallContextFactory internalCallContextFactory, final PaymentConfig paymentConfig,
- final NonEntityDao nonEntityDao, final PaymentDao paymentDao, final Clock clock,
- final PaymentStateMachineHelper paymentStateMachineHelper, final RetryStateMachineHelper retrySMHelper, final CacheControllerDispatcher controllerDispatcher, final AccountInternalApi accountInternalApi,
- final PluginRoutingPaymentAutomatonRunner pluginControlledPaymentAutomatonRunner, final OSGIServiceRegistration<PaymentPluginApi> pluginRegistry) {
- super(janitor, internalCallContextFactory, paymentConfig, nonEntityDao, paymentDao, clock, paymentStateMachineHelper, retrySMHelper, controllerDispatcher, accountInternalApi, pluginControlledPaymentAutomatonRunner, pluginRegistry);
+ final PaymentDao paymentDao, final Clock clock,
+ final PaymentStateMachineHelper paymentStateMachineHelper, final RetryStateMachineHelper retrySMHelper, final AccountInternalApi accountInternalApi,
+ final PluginRoutingPaymentAutomatonRunner pluginControlledPaymentAutomatonRunner, final OSGIServiceRegistration<PaymentPluginApi> pluginRegistry) {
+ super(janitor, internalCallContextFactory, paymentConfig, paymentDao, clock, paymentStateMachineHelper, retrySMHelper, accountInternalApi, pluginControlledPaymentAutomatonRunner, pluginRegistry);
}
@Override
public List<PaymentModelDao> getItemsForIteration() {
// In theory this should be the plugin timeout but we add a 3 minutes delay for safety.
- int delayBeforeNow = (int) paymentConfig.getPaymentPluginTimeout().getMillis() + SAFETY_DELAY_MS;
+ final int delayBeforeNow = (int) paymentConfig.getPaymentPluginTimeout().getMillis() + SAFETY_DELAY_MS;
final DateTime createdBeforeDate = clock.getUTCNow().minusMillis(delayBeforeNow);
// We want to avoid iterating on the same failed payments -- if for some reasons they can't fix themselves.
@@ -84,13 +81,12 @@ public class ErroredPaymentTask extends CompletionTaskBase<PaymentModelDao> {
@Override
public void doIteration(final PaymentModelDao item) {
-
- final InternalTenantContext internalTenantContext = internalCallContextFactory.createInternalTenantContext(item.getAccountId(), item.getId(), ObjectType.PAYMENT);
+ final InternalTenantContext internalTenantContext = internalCallContextFactory.createInternalTenantContext(item.getTenantRecordId(), item.getAccountRecordId());
final CallContext callContext = createCallContext("ErroredPaymentTask", internalTenantContext);
final InternalCallContext internalCallContext = internalCallContextFactory.createInternalCallContext(item.getAccountId(), callContext);
final List<PaymentTransactionModelDao> transactions = paymentDao.getTransactionsForPayment(item.getId(), internalTenantContext);
- Preconditions.checkState(! transactions.isEmpty(), "Janitor ErroredPaymentTask found item " + item.getId() + " with no transactions, skipping");
+ Preconditions.checkState(!transactions.isEmpty(), "Janitor ErroredPaymentTask found item " + item.getId() + " with no transactions, skipping");
// We look for latest transaction in an UNKNOWN state, if not we skip
final PaymentTransactionModelDao unknownTransaction = transactions.get(transactions.size() - 1);
@@ -101,7 +97,6 @@ public class ErroredPaymentTask extends CompletionTaskBase<PaymentModelDao> {
final PaymentMethodModelDao paymentMethod = paymentDao.getPaymentMethod(item.getPaymentMethodId(), internalCallContext);
final PaymentPluginApi paymentPluginApi = getPaymentPluginApi(item, paymentMethod.getPluginName());
-
PaymentTransactionInfoPlugin pluginErroredTransaction = null;
try {
final List<PaymentTransactionInfoPlugin> result = paymentPluginApi.getPaymentInfo(item.getAccountId(), item.getId(), ImmutableList.<PluginProperty>of(), callContext);
@@ -112,7 +107,7 @@ public class ErroredPaymentTask extends CompletionTaskBase<PaymentModelDao> {
return input.getKbTransactionPaymentId().equals(unknownTransaction.getId());
}
}).orNull();
- } catch (PaymentPluginApiException ignored) {
+ } catch (final PaymentPluginApiException ignored) {
}
@@ -143,8 +138,7 @@ public class ErroredPaymentTask extends CompletionTaskBase<PaymentModelDao> {
}
final String lastSuccessPaymentState = paymentStateMachineHelper.isSuccessState(newPaymentState) ? newPaymentState : null;
-
- final BigDecimal processedAmount = pluginErroredTransaction != null ? pluginErroredTransaction.getAmount() : null;
+ final BigDecimal processedAmount = pluginErroredTransaction != null ? pluginErroredTransaction.getAmount() : null;
final Currency processedCurrency = pluginErroredTransaction != null ? pluginErroredTransaction.getCurrency() : null;
final String gatewayErrorCode = pluginErroredTransaction != null ? pluginErroredTransaction.getGatewayErrorCode() : null;
final String gatewayError = pluginErroredTransaction != null ? pluginErroredTransaction.getGatewayError() : null;
diff --git a/payment/src/main/java/org/killbill/billing/payment/core/janitor/Janitor.java b/payment/src/main/java/org/killbill/billing/payment/core/janitor/Janitor.java
index a87d870..cd39edc 100644
--- a/payment/src/main/java/org/killbill/billing/payment/core/janitor/Janitor.java
+++ b/payment/src/main/java/org/killbill/billing/payment/core/janitor/Janitor.java
@@ -1,6 +1,6 @@
/*
- * Copyright 2014 Groupon, Inc
- * Copyright 2014 The Billing Project, LLC
+ * Copyright 2014-2015 Groupon, Inc
+ * Copyright 2014-2015 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
@@ -31,10 +31,8 @@ import org.killbill.billing.payment.core.sm.RetryStateMachineHelper;
import org.killbill.billing.payment.dao.PaymentDao;
import org.killbill.billing.payment.glue.PaymentModule;
import org.killbill.billing.payment.plugin.api.PaymentPluginApi;
-import org.killbill.billing.util.cache.CacheControllerDispatcher;
import org.killbill.billing.util.callcontext.InternalCallContextFactory;
import org.killbill.billing.util.config.PaymentConfig;
-import org.killbill.billing.util.dao.NonEntityDao;
import org.killbill.clock.Clock;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -44,9 +42,9 @@ import org.slf4j.LoggerFactory;
*/
public class Janitor {
- private final static Logger log = LoggerFactory.getLogger(Janitor.class);
+ private static final Logger log = LoggerFactory.getLogger(Janitor.class);
- private final static int TERMINATION_TIMEOUT_SEC = 5;
+ private static final int TERMINATION_TIMEOUT_SEC = 5;
private final ScheduledExecutorService janitorExecutor;
private final PaymentConfig paymentConfig;
@@ -61,22 +59,20 @@ public class Janitor {
final PaymentDao paymentDao,
final PaymentConfig paymentConfig,
final Clock clock,
- final NonEntityDao nonEntityDao,
final InternalCallContextFactory internalCallContextFactory,
final PluginRoutingPaymentAutomatonRunner pluginControlledPaymentAutomatonRunner,
@Named(PaymentModule.JANITOR_EXECUTOR_NAMED) final ScheduledExecutorService janitorExecutor,
final PaymentStateMachineHelper paymentSMHelper,
final RetryStateMachineHelper retrySMHelper,
- final CacheControllerDispatcher controllerDispatcher,
final OSGIServiceRegistration<PaymentPluginApi> pluginRegistry) {
this.janitorExecutor = janitorExecutor;
this.paymentConfig = paymentConfig;
- this.pendingTransactionTask = new PendingTransactionTask(this, internalCallContextFactory, paymentConfig, nonEntityDao, paymentDao, clock, paymentSMHelper, retrySMHelper,
- controllerDispatcher, accountInternalApi, pluginControlledPaymentAutomatonRunner, pluginRegistry);
- this.attemptCompletionTask = new AttemptCompletionTask(this, internalCallContextFactory, paymentConfig, nonEntityDao, paymentDao, clock, paymentSMHelper, retrySMHelper,
- controllerDispatcher, accountInternalApi, pluginControlledPaymentAutomatonRunner, pluginRegistry);
- this.erroredPaymentCompletionTask = new ErroredPaymentTask(this, internalCallContextFactory, paymentConfig, nonEntityDao, paymentDao, clock, paymentSMHelper, retrySMHelper,
- controllerDispatcher, accountInternalApi, pluginControlledPaymentAutomatonRunner, pluginRegistry);
+ this.pendingTransactionTask = new PendingTransactionTask(this, internalCallContextFactory, paymentConfig, paymentDao, clock, paymentSMHelper, retrySMHelper,
+ accountInternalApi, pluginControlledPaymentAutomatonRunner, pluginRegistry);
+ this.attemptCompletionTask = new AttemptCompletionTask(this, internalCallContextFactory, paymentConfig, paymentDao, clock, paymentSMHelper, retrySMHelper,
+ accountInternalApi, pluginControlledPaymentAutomatonRunner, pluginRegistry);
+ this.erroredPaymentCompletionTask = new ErroredPaymentTask(this, internalCallContextFactory, paymentConfig, paymentDao, clock, paymentSMHelper, retrySMHelper,
+ accountInternalApi, pluginControlledPaymentAutomatonRunner, pluginRegistry);
this.isStopped = false;
}
@@ -114,11 +110,11 @@ public class Janitor {
* Then, awaitTermination with a timeout is required to ensure tasks completed.
*/
janitorExecutor.shutdown();
- boolean success = janitorExecutor.awaitTermination(TERMINATION_TIMEOUT_SEC, TimeUnit.SECONDS);
+ final boolean success = janitorExecutor.awaitTermination(TERMINATION_TIMEOUT_SEC, TimeUnit.SECONDS);
if (!success) {
log.warn("Janitor failed to complete termination within " + TERMINATION_TIMEOUT_SEC + "sec");
}
- } catch (InterruptedException e) {
+ } catch (final InterruptedException e) {
Thread.currentThread().interrupt();
log.warn("Janitor stop sequence got interrupted");
} finally {
diff --git a/payment/src/main/java/org/killbill/billing/payment/core/janitor/PendingTransactionTask.java b/payment/src/main/java/org/killbill/billing/payment/core/janitor/PendingTransactionTask.java
index d5f40d0..97c65a4 100644
--- a/payment/src/main/java/org/killbill/billing/payment/core/janitor/PendingTransactionTask.java
+++ b/payment/src/main/java/org/killbill/billing/payment/core/janitor/PendingTransactionTask.java
@@ -1,6 +1,6 @@
/*
- * Copyright 2014 Groupon, Inc
- * Copyright 2014 The Billing Project, LLC
+ * Copyright 2014-2015 Groupon, Inc
+ * Copyright 2014-2015 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
@@ -27,10 +27,8 @@ import org.killbill.billing.payment.core.sm.PluginRoutingPaymentAutomatonRunner;
import org.killbill.billing.payment.core.sm.RetryStateMachineHelper;
import org.killbill.billing.payment.dao.PaymentDao;
import org.killbill.billing.payment.plugin.api.PaymentPluginApi;
-import org.killbill.billing.util.cache.CacheControllerDispatcher;
import org.killbill.billing.util.callcontext.InternalCallContextFactory;
import org.killbill.billing.util.config.PaymentConfig;
-import org.killbill.billing.util.dao.NonEntityDao;
import org.killbill.clock.Clock;
import com.google.common.collect.ImmutableList;
@@ -40,14 +38,13 @@ import com.google.common.collect.ImmutableList;
*/
final class PendingTransactionTask extends CompletionTaskBase<Integer> {
- private Janitor janitor;
private final List<Integer> itemsForIterations;
public PendingTransactionTask(final Janitor janitor, final InternalCallContextFactory internalCallContextFactory, final PaymentConfig paymentConfig,
- final NonEntityDao nonEntityDao, final PaymentDao paymentDao, final Clock clock, final PaymentStateMachineHelper paymentStateMachineHelper,
- final RetryStateMachineHelper retrySMHelper, final CacheControllerDispatcher controllerDispatcher, final AccountInternalApi accountInternalApi,
- final PluginRoutingPaymentAutomatonRunner pluginControlledPaymentAutomatonRunner, final OSGIServiceRegistration<PaymentPluginApi> pluginRegistry) {
- super(janitor, internalCallContextFactory, paymentConfig, nonEntityDao, paymentDao, clock, paymentStateMachineHelper, retrySMHelper, controllerDispatcher, accountInternalApi, pluginControlledPaymentAutomatonRunner, pluginRegistry);
+ final PaymentDao paymentDao, final Clock clock, final PaymentStateMachineHelper paymentStateMachineHelper,
+ final RetryStateMachineHelper retrySMHelper, final AccountInternalApi accountInternalApi,
+ final PluginRoutingPaymentAutomatonRunner pluginControlledPaymentAutomatonRunner, final OSGIServiceRegistration<PaymentPluginApi> pluginRegistry) {
+ super(janitor, internalCallContextFactory, paymentConfig, paymentDao, clock, paymentStateMachineHelper, retrySMHelper, accountInternalApi, pluginControlledPaymentAutomatonRunner, pluginRegistry);
this.itemsForIterations = ImmutableList.of(new Integer(1));
}
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 e01c8ab..4a3d16f 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
@@ -1,6 +1,6 @@
/*
- * Copyright 2014 Groupon, Inc
- * Copyright 2014 The Billing Project, LLC
+ * Copyright 2014-2015 Groupon, Inc
+ * Copyright 2014-2015 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
@@ -39,10 +39,9 @@ import org.killbill.billing.payment.plugin.api.HostedPaymentPageFormDescriptor;
import org.killbill.billing.payment.plugin.api.PaymentPluginApi;
import org.killbill.billing.payment.plugin.api.PaymentPluginApiException;
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.InternalCallContextFactory;
import org.killbill.billing.util.config.PaymentConfig;
-import org.killbill.billing.util.dao.NonEntityDao;
import org.killbill.clock.Clock;
import org.killbill.commons.locker.GlobalLocker;
import org.slf4j.Logger;
@@ -71,13 +70,12 @@ public class PaymentGatewayProcessor extends ProcessorBase {
final InvoiceInternalApi invoiceApi,
final TagInternalApi tagUserApi,
final PaymentDao paymentDao,
- final NonEntityDao nonEntityDao,
final GlobalLocker locker,
final PaymentConfig paymentConfig,
@Named(PLUGIN_EXECUTOR_NAMED) final ExecutorService executor,
- final Clock clock,
- final CacheControllerDispatcher controllerDispatcher) {
- super(pluginRegistry, accountUserApi, paymentDao, nonEntityDao, tagUserApi, locker, executor, invoiceApi, clock, controllerDispatcher);
+ final InternalCallContextFactory internalCallContextFactory,
+ final Clock clock) {
+ super(pluginRegistry, accountUserApi, paymentDao, tagUserApi, locker, executor, internalCallContextFactory, invoiceApi, clock);
final long paymentPluginTimeoutSec = TimeUnit.SECONDS.convert(paymentConfig.getPaymentPluginTimeout().getPeriod(), paymentConfig.getPaymentPluginTimeout().getUnit());
this.paymentPluginFormDispatcher = new PluginDispatcher<HostedPaymentPageFormDescriptor>(paymentPluginTimeoutSec, executor);
this.paymentPluginNotificationDispatcher = new PluginDispatcher<GatewayNotification>(paymentPluginTimeoutSec, executor);
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 2f3e668..d179396 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
@@ -1,7 +1,7 @@
/*
* Copyright 2010-2013 Ning, Inc.
- * Copyright 2014 Groupon, Inc
- * Copyright 2014 The Billing Project, LLC
+ * Copyright 2014-2015 Groupon, Inc
+ * Copyright 2014-2015 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
@@ -52,11 +52,10 @@ 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.cache.CacheControllerDispatcher;
import org.killbill.billing.util.callcontext.CallContext;
+import org.killbill.billing.util.callcontext.InternalCallContextFactory;
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;
import org.killbill.billing.util.entity.dao.DefaultPaginationHelper.SourcePaginationBuilder;
@@ -87,14 +86,13 @@ public class PaymentMethodProcessor extends ProcessorBase {
final AccountInternalApi accountInternalApi,
final InvoiceInternalApi invoiceApi,
final PaymentDao paymentDao,
- 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 InternalCallContextFactory internalCallContextFactory,
+ final Clock clock) {
+ super(pluginRegistry, accountInternalApi, paymentDao, tagUserApi, locker, executor, internalCallContextFactory, invoiceApi, clock);
final long paymentPluginTimeoutSec = TimeUnit.SECONDS.convert(paymentConfig.getPaymentPluginTimeout().getPeriod(), paymentConfig.getPaymentPluginTimeout().getUnit());
this.uuidPluginNotificationDispatcher = new PluginDispatcher<UUID>(paymentPluginTimeoutSec, executor);
}
diff --git a/payment/src/main/java/org/killbill/billing/payment/core/PaymentProcessor.java b/payment/src/main/java/org/killbill/billing/payment/core/PaymentProcessor.java
index f78753d..ffc9030 100644
--- a/payment/src/main/java/org/killbill/billing/payment/core/PaymentProcessor.java
+++ b/payment/src/main/java/org/killbill/billing/payment/core/PaymentProcessor.java
@@ -1,7 +1,7 @@
/*
* Copyright 2010-2013 Ning, Inc.
- * Copyright 2014 Groupon, Inc
- * Copyright 2014 The Billing Project, LLC
+ * Copyright 2014-2015 Groupon, Inc
+ * Copyright 2014-2015 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
@@ -57,11 +57,9 @@ import org.killbill.billing.payment.plugin.api.PaymentPluginApi;
import org.killbill.billing.payment.plugin.api.PaymentPluginApiException;
import org.killbill.billing.payment.plugin.api.PaymentTransactionInfoPlugin;
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.InternalCallContextFactory;
import org.killbill.billing.util.callcontext.TenantContext;
-import org.killbill.billing.util.dao.NonEntityDao;
import org.killbill.billing.util.entity.Pagination;
import org.killbill.billing.util.entity.dao.DefaultPaginationHelper.EntityPaginationBuilder;
import org.killbill.billing.util.entity.dao.DefaultPaginationHelper.SourcePaginationBuilder;
@@ -87,7 +85,6 @@ public class PaymentProcessor extends ProcessorBase {
private static final ImmutableList<PluginProperty> PLUGIN_PROPERTIES = ImmutableList.<PluginProperty>of();
private final PaymentAutomatonRunner paymentAutomatonRunner;
- private final InternalCallContextFactory internalCallContextFactory;
private static final Logger log = LoggerFactory.getLogger(PaymentProcessor.class);
@@ -97,15 +94,12 @@ public class PaymentProcessor extends ProcessorBase {
final InvoiceInternalApi invoiceApi,
final TagInternalApi tagUserApi,
final PaymentDao paymentDao,
- final NonEntityDao nonEntityDao,
final InternalCallContextFactory internalCallContextFactory,
final GlobalLocker locker,
@Named(PLUGIN_EXECUTOR_NAMED) final ExecutorService executor,
final PaymentAutomatonRunner paymentAutomatonRunner,
- final Clock clock,
- final CacheControllerDispatcher controllerDispatcher) {
- super(pluginRegistry, accountUserApi, paymentDao, nonEntityDao, tagUserApi, locker, executor, invoiceApi, clock, controllerDispatcher);
- this.internalCallContextFactory = internalCallContextFactory;
+ final Clock clock) {
+ super(pluginRegistry, accountUserApi, paymentDao, tagUserApi, locker, executor, internalCallContextFactory, invoiceApi, clock);
this.paymentAutomatonRunner = paymentAutomatonRunner;
}
diff --git a/payment/src/main/java/org/killbill/billing/payment/core/PluginRoutingPaymentProcessor.java b/payment/src/main/java/org/killbill/billing/payment/core/PluginRoutingPaymentProcessor.java
index 79be2f0..a6ca074 100644
--- a/payment/src/main/java/org/killbill/billing/payment/core/PluginRoutingPaymentProcessor.java
+++ b/payment/src/main/java/org/killbill/billing/payment/core/PluginRoutingPaymentProcessor.java
@@ -1,7 +1,8 @@
/*
- * Copyright 2014 Groupon, Inc
+ * Copyright 2014-2015 Groupon, Inc
+ * Copyright 2014-2015 The Billing Project, LLC
*
- * Groupon 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:
*
@@ -27,7 +28,6 @@ import javax.inject.Inject;
import org.killbill.automaton.MissingEntryException;
import org.killbill.automaton.State;
-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;
@@ -48,10 +48,8 @@ import org.killbill.billing.payment.dao.PluginPropertySerializer;
import org.killbill.billing.payment.dao.PluginPropertySerializer.PluginPropertySerializerException;
import org.killbill.billing.payment.plugin.api.PaymentPluginApi;
import org.killbill.billing.tag.TagInternalApi;
-import org.killbill.billing.util.cache.Cachable.CacheType;
-import org.killbill.billing.util.cache.CacheControllerDispatcher;
import org.killbill.billing.util.callcontext.CallContext;
-import org.killbill.billing.util.dao.NonEntityDao;
+import org.killbill.billing.util.callcontext.InternalCallContextFactory;
import org.killbill.clock.Clock;
import org.killbill.commons.locker.GlobalLocker;
@@ -67,7 +65,6 @@ public class PluginRoutingPaymentProcessor extends ProcessorBase {
private final PluginRoutingPaymentAutomatonRunner pluginControlledPaymentAutomatonRunner;
private final RetryStateMachineHelper retrySMHelper;
- private final CacheControllerDispatcher controllerDispatcher;
@Inject
public PluginRoutingPaymentProcessor(final OSGIServiceRegistration<PaymentPluginApi> pluginRegistry,
@@ -75,17 +72,15 @@ public class PluginRoutingPaymentProcessor extends ProcessorBase {
final InvoiceInternalApi invoiceApi,
final TagInternalApi tagUserApi,
final PaymentDao paymentDao,
- final NonEntityDao nonEntityDao,
final GlobalLocker locker,
@Named(PLUGIN_EXECUTOR_NAMED) final ExecutorService executor,
+ final InternalCallContextFactory internalCallContextFactory,
final PluginRoutingPaymentAutomatonRunner pluginControlledPaymentAutomatonRunner,
final RetryStateMachineHelper retrySMHelper,
- final Clock clock,
- final CacheControllerDispatcher controllerDispatcher) {
- super(pluginRegistry, accountInternalApi, paymentDao, nonEntityDao, tagUserApi, locker, executor, invoiceApi, clock, controllerDispatcher);
+ final Clock clock) {
+ super(pluginRegistry, accountInternalApi, paymentDao, tagUserApi, locker, executor, internalCallContextFactory, invoiceApi, clock);
this.retrySMHelper = retrySMHelper;
this.pluginControlledPaymentAutomatonRunner = pluginControlledPaymentAutomatonRunner;
- this.controllerDispatcher = controllerDispatcher;
}
public Payment createAuthorization(final boolean isApiPayment, final Account account, final UUID paymentMethodId, @Nullable final UUID paymentId, final BigDecimal amount, final Currency currency, final String paymentExternalKey, final String transactionExternalKey,
@@ -212,8 +207,7 @@ public class PluginRoutingPaymentProcessor extends ProcessorBase {
final Iterable<PluginProperty> pluginProperties = PluginPropertySerializer.deserialize(attempt.getPluginProperties());
final Account account = accountInternalApi.getAccountById(attempt.getAccountId(), internalCallContext);
- final UUID tenantId = nonEntityDao.retrieveIdFromObject(internalCallContext.getTenantRecordId(), ObjectType.TENANT, controllerDispatcher.getCacheController(CacheType.OBJECT_ID));
- final CallContext callContext = internalCallContext.toCallContext(tenantId);
+ final CallContext callContext = buildCallContext(internalCallContext);
final State state = retrySMHelper.getState(attempt.getStateName());
pluginControlledPaymentAutomatonRunner.run(state,
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 d9da5e2..9d70fe7 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
@@ -1,7 +1,7 @@
/*
* Copyright 2010-2013 Ning, Inc.
- * Copyright 2014 Groupon, Inc
- * Copyright 2014 The Billing Project, LLC
+ * Copyright 2014-2015 Groupon, Inc
+ * Copyright 2014-2015 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
@@ -46,10 +46,9 @@ import org.killbill.billing.payment.dispatcher.PluginDispatcher.PluginDispatcher
import org.killbill.billing.payment.plugin.api.PaymentPluginApi;
import org.killbill.billing.tag.TagInternalApi;
import org.killbill.billing.util.api.TagApiException;
-import org.killbill.billing.util.cache.Cachable.CacheType;
-import org.killbill.billing.util.cache.CacheControllerDispatcher;
+import org.killbill.billing.util.callcontext.CallContext;
+import org.killbill.billing.util.callcontext.InternalCallContextFactory;
import org.killbill.billing.util.callcontext.TenantContext;
-import org.killbill.billing.util.dao.NonEntityDao;
import org.killbill.billing.util.globallocker.LockerType;
import org.killbill.billing.util.tag.ControlTagType;
import org.killbill.billing.util.tag.Tag;
@@ -75,10 +74,9 @@ public abstract class ProcessorBase {
protected final GlobalLocker locker;
protected final ExecutorService executor;
protected final PaymentDao paymentDao;
- protected final NonEntityDao nonEntityDao;
+ protected final InternalCallContextFactory internalCallContextFactory;
protected final TagInternalApi tagInternalApi;
protected final Clock clock;
- protected final CacheControllerDispatcher controllerDispatcher;
protected static final Logger log = LoggerFactory.getLogger(ProcessorBase.class);
protected final InvoiceInternalApi invoiceApi;
@@ -86,23 +84,21 @@ public abstract class ProcessorBase {
public ProcessorBase(final OSGIServiceRegistration<PaymentPluginApi> pluginRegistry,
final AccountInternalApi accountInternalApi,
final PaymentDao paymentDao,
- final NonEntityDao nonEntityDao,
final TagInternalApi tagInternalApi,
final GlobalLocker locker,
final ExecutorService executor,
+ final InternalCallContextFactory internalCallContextFactory,
final InvoiceInternalApi invoiceApi,
- final Clock clock,
- final CacheControllerDispatcher controllerDispatcher) {
+ final Clock clock) {
this.pluginRegistry = pluginRegistry;
this.accountInternalApi = accountInternalApi;
this.paymentDao = paymentDao;
- this.nonEntityDao = nonEntityDao;
this.locker = locker;
this.executor = executor;
this.tagInternalApi = tagInternalApi;
+ this.internalCallContextFactory = internalCallContextFactory;
this.invoiceApi = invoiceApi;
this.clock = clock;
- this.controllerDispatcher = controllerDispatcher;
}
protected boolean isAccountAutoPayOff(final UUID accountId, final InternalTenantContext context) {
@@ -161,7 +157,11 @@ public abstract class ProcessorBase {
}
protected TenantContext buildTenantContext(final InternalTenantContext context) {
- return context.toTenantContext(nonEntityDao.retrieveIdFromObject(context.getTenantRecordId(), ObjectType.TENANT, controllerDispatcher.getCacheController(CacheType.OBJECT_ID)));
+ return internalCallContextFactory.createTenantContext(context);
+ }
+
+ protected CallContext buildCallContext(final InternalCallContext context) {
+ return internalCallContextFactory.createCallContext(context);
}
protected void validateUniqueTransactionExternalKey(@Nullable final String transactionExternalKey, final InternalTenantContext tenantContext) throws PaymentApiException {
diff --git a/payment/src/main/java/org/killbill/billing/payment/core/sm/RetryEnteringStateCallback.java b/payment/src/main/java/org/killbill/billing/payment/core/sm/RetryEnteringStateCallback.java
index d2d0ce3..d2dd835 100644
--- a/payment/src/main/java/org/killbill/billing/payment/core/sm/RetryEnteringStateCallback.java
+++ b/payment/src/main/java/org/killbill/billing/payment/core/sm/RetryEnteringStateCallback.java
@@ -1,7 +1,8 @@
/*
- * Copyright 2014 Groupon, Inc
+ * Copyright 2014-2015 Groupon, Inc
+ * Copyright 2014-2015 The Billing Project, LLC
*
- * Groupon 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:
*
@@ -49,7 +50,7 @@ public class RetryEnteringStateCallback implements EnteringStateCallback {
retryablePaymentAutomatonRunner.paymentDao.updatePaymentAttempt(attempt.getId(), transactionId, state.getName(), paymentStateContext.internalCallContext);
if ("RETRIED".equals(state.getName())) {
- retryServiceScheduler.scheduleRetry(ObjectType.PAYMENT_ATTEMPT, attempt.getId(), attempt.getId(),
+ retryServiceScheduler.scheduleRetry(ObjectType.PAYMENT_ATTEMPT, attempt.getId(), attempt.getId(), attempt.getTenantRecordId(),
paymentStateContext.getPaymentControlPluginNames(), paymentStateContext.getRetryDate());
}
}
diff --git a/payment/src/main/java/org/killbill/billing/payment/invoice/InvoicePaymentRoutingPluginApi.java b/payment/src/main/java/org/killbill/billing/payment/invoice/InvoicePaymentRoutingPluginApi.java
index ca44ef9..5760da4 100644
--- a/payment/src/main/java/org/killbill/billing/payment/invoice/InvoicePaymentRoutingPluginApi.java
+++ b/payment/src/main/java/org/killbill/billing/payment/invoice/InvoicePaymentRoutingPluginApi.java
@@ -1,7 +1,8 @@
/*
- * Copyright 2014 Groupon, Inc
+ * Copyright 2014-2015 Groupon, Inc
+ * Copyright 2014-2015 The Billing Project, LLC
*
- * Groupon 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:
*
@@ -40,12 +41,12 @@ import org.killbill.billing.invoice.api.InvoicePayment;
import org.killbill.billing.payment.api.PluginProperty;
import org.killbill.billing.payment.api.TransactionStatus;
import org.killbill.billing.payment.api.TransactionType;
-import org.killbill.billing.payment.invoice.dao.InvoicePaymentRoutingDao;
-import org.killbill.billing.payment.invoice.dao.PluginAutoPayOffModelDao;
import org.killbill.billing.payment.dao.PaymentDao;
import org.killbill.billing.payment.dao.PaymentModelDao;
import org.killbill.billing.payment.dao.PaymentTransactionModelDao;
import org.killbill.billing.payment.glue.PaymentModule;
+import org.killbill.billing.payment.invoice.dao.InvoicePaymentRoutingDao;
+import org.killbill.billing.payment.invoice.dao.PluginAutoPayOffModelDao;
import org.killbill.billing.payment.retry.BaseRetryService.RetryServiceScheduler;
import org.killbill.billing.payment.retry.DefaultFailureCallResult;
import org.killbill.billing.payment.retry.DefaultPriorPaymentRoutingResult;
@@ -76,10 +77,10 @@ import com.google.common.collect.Iterables;
public final class InvoicePaymentRoutingPluginApi implements PaymentRoutingPluginApi {
- public final static String CREATED_BY = "InvoicePaymentRoutingPluginApi";
+ public static final String CREATED_BY = "InvoicePaymentRoutingPluginApi";
/* Don't change value String for properties as they are referenced from jaxrs without the constants which are not accessible */
- public final static String PLUGIN_NAME = "__INVOICE_PAYMENT_CONTROL_PLUGIN__";
+ public static final String PLUGIN_NAME = "__INVOICE_PAYMENT_CONTROL_PLUGIN__";
public static final String PROP_IPCD_INVOICE_ID = "IPCD_INVOICE_ID";
public static final String PROP_IPCD_REFUND_IDS_WITH_AMOUNT_KEY = "IPCD_REFUND_IDS_AMOUNTS";
public static final String PROP_IPCD_REFUND_WITH_ADJUSTMENTS = "IPCD_REFUND_WITH_ADJUSTMENTS";
@@ -111,7 +112,7 @@ public final class InvoicePaymentRoutingPluginApi implements PaymentRoutingPlugi
}
@Override
- public PriorPaymentRoutingResult priorCall(final PaymentRoutingContext paymentRoutingContext, Iterable<PluginProperty> properties) throws PaymentRoutingApiException {
+ public PriorPaymentRoutingResult priorCall(final PaymentRoutingContext paymentRoutingContext, final Iterable<PluginProperty> properties) throws PaymentRoutingApiException {
final TransactionType transactionType = paymentRoutingContext.getTransactionType();
Preconditions.checkArgument(transactionType == TransactionType.PURCHASE ||
@@ -132,7 +133,7 @@ public final class InvoicePaymentRoutingPluginApi implements PaymentRoutingPlugi
}
@Override
- public OnSuccessPaymentRoutingResult onSuccessCall(final PaymentRoutingContext paymentRoutingContext, Iterable<PluginProperty> properties) throws PaymentRoutingApiException {
+ public OnSuccessPaymentRoutingResult onSuccessCall(final PaymentRoutingContext paymentRoutingContext, final Iterable<PluginProperty> properties) throws PaymentRoutingApiException {
final TransactionType transactionType = paymentRoutingContext.getTransactionType();
Preconditions.checkArgument(transactionType == TransactionType.PURCHASE ||
@@ -183,15 +184,15 @@ public final class InvoicePaymentRoutingPluginApi implements PaymentRoutingPlugi
default:
throw new IllegalStateException("Unexpected transactionType " + transactionType);
}
- } catch (InvoiceApiException e) {
+ } catch (final InvoiceApiException e) {
logger.error("InvoicePaymentRoutingPluginApi onSuccessCall failed for attemptId = " + paymentRoutingContext.getAttemptPaymentId() + ", transactionType = " + transactionType, e);
}
return null;
}
@Override
- public OnFailurePaymentRoutingResult onFailureCall(final PaymentRoutingContext paymentRoutingContext, Iterable<PluginProperty> properties) throws
- PaymentRoutingApiException {
+ public OnFailurePaymentRoutingResult onFailureCall(final PaymentRoutingContext paymentRoutingContext, final Iterable<PluginProperty> properties) throws
+ PaymentRoutingApiException {
final InternalCallContext internalContext = internalCallContextFactory.createInternalCallContext(paymentRoutingContext.getAccountId(), paymentRoutingContext);
final TransactionType transactionType = paymentRoutingContext.getTransactionType();
@@ -210,9 +211,9 @@ public final class InvoicePaymentRoutingPluginApi implements PaymentRoutingPlugi
public void process_AUTO_PAY_OFF_removal(final Account account, final InternalCallContext internalCallContext) {
final List<PluginAutoPayOffModelDao> entries = controlDao.getAutoPayOffEntry(account.getId());
- for (PluginAutoPayOffModelDao cur : entries) {
+ for (final PluginAutoPayOffModelDao cur : entries) {
// TODO In theory we should pass not only PLUGIN_NAME, but also all the plugin list associated which the original call
- retryServiceScheduler.scheduleRetry(ObjectType.ACCOUNT, account.getId(), cur.getAttemptId(), ImmutableList.<String>of(PLUGIN_NAME), clock.getUTCNow());
+ retryServiceScheduler.scheduleRetry(ObjectType.ACCOUNT, account.getId(), cur.getAttemptId(), internalCallContext.getTenantRecordId(), ImmutableList.<String>of(PLUGIN_NAME), clock.getUTCNow());
}
controlDao.removeAutoPayOffEntry(account.getId());
}
@@ -245,9 +246,9 @@ public final class InvoicePaymentRoutingPluginApi implements PaymentRoutingPlugi
} else {
return new DefaultPriorPaymentRoutingResult(isAborted, requestedAmount, null, null);
}
- } catch (InvoiceApiException e) {
+ } catch (final InvoiceApiException e) {
throw new PaymentRoutingApiException(e);
- } catch (IllegalArgumentException e) {
+ } catch (final IllegalArgumentException e) {
throw new PaymentRoutingApiException(e);
}
}
@@ -323,7 +324,7 @@ public final class InvoicePaymentRoutingPluginApi implements PaymentRoutingPlugi
amountFromItems = amountFromItems.add(Objects.firstNonNull(specifiedItemAmount, itemAmount));
}
return amountFromItems;
- } catch (InvoiceApiException e) {
+ } catch (final InvoiceApiException e) {
throw new PaymentRoutingApiException(e);
}
}
@@ -369,12 +370,12 @@ public final class InvoicePaymentRoutingPluginApi implements PaymentRoutingPlugi
final int attemptsInState = getNumberAttemptsInState(purchasedTransactions, TransactionStatus.PAYMENT_FAILURE);
final int retryCount = (attemptsInState - 1) >= 0 ? (attemptsInState - 1) : 0;
if (retryCount < retryDays.size()) {
- int retryInDays;
+ final int retryInDays;
final DateTime nextRetryDate = clock.getUTCNow();
try {
retryInDays = retryDays.get(retryCount);
result = nextRetryDate.plusDays(retryInDays);
- } catch (NumberFormatException ex) {
+ } catch (final NumberFormatException ex) {
logger.error("Could not get retry day for retry count {}", retryCount);
}
}
diff --git a/payment/src/main/java/org/killbill/billing/payment/retry/BaseRetryService.java b/payment/src/main/java/org/killbill/billing/payment/retry/BaseRetryService.java
index 659d344..21f0a3b 100644
--- a/payment/src/main/java/org/killbill/billing/payment/retry/BaseRetryService.java
+++ b/payment/src/main/java/org/killbill/billing/payment/retry/BaseRetryService.java
@@ -1,7 +1,7 @@
/*
* Copyright 2010-2013 Ning, Inc.
- * Copyright 2014 Groupon, Inc
- * Copyright 2014 The Billing Project, LLC
+ * Copyright 2014-2015 Groupon, Inc
+ * Copyright 2014-2015 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
@@ -105,13 +105,12 @@ public abstract class BaseRetryService implements RetryService {
this.internalCallContextFactory = internalCallContextFactory;
}
- public boolean scheduleRetry(final ObjectType objectType, final UUID objectId, final UUID attemptId, final List<String> paymentControlPluginNames, final DateTime timeOfRetry) {
- return scheduleRetryInternal(objectType, objectId, attemptId, paymentControlPluginNames, timeOfRetry, null);
+ public boolean scheduleRetry(final ObjectType objectType, final UUID objectId, final UUID attemptId, final Long tenantRecordId, final List<String> paymentControlPluginNames, final DateTime timeOfRetry) {
+ return scheduleRetryInternal(objectType, objectId, attemptId, tenantRecordId, paymentControlPluginNames, timeOfRetry, null);
}
-
- private boolean scheduleRetryInternal(final ObjectType objectType, final UUID objectId, final UUID attemptId, final List<String> paymentControlPluginNames, final DateTime timeOfRetry, final EntitySqlDaoWrapperFactory<EntitySqlDao> transactionalDao) {
- final InternalCallContext context = createCallContextFromPaymentId(objectType, objectId);
+ private boolean scheduleRetryInternal(final ObjectType objectType, final UUID objectId, final UUID attemptId, final Long tenantRecordId, final List<String> paymentControlPluginNames, final DateTime timeOfRetry, final EntitySqlDaoWrapperFactory<EntitySqlDao> transactionalDao) {
+ final InternalCallContext context = createCallContextFromPaymentId(objectType, objectId, tenantRecordId);
try {
final NotificationQueue retryQueue = notificationQueueService.getNotificationQueue(DefaultPaymentService.SERVICE_NAME, getQueueName());
@@ -123,18 +122,18 @@ public abstract class BaseRetryService implements RetryService {
retryQueue.recordFutureNotificationFromTransaction(transactionalDao.getSqlDao(), timeOfRetry, key, context.getUserToken(), context.getAccountRecordId(), context.getTenantRecordId());
}
}
- } catch (NoSuchNotificationQueue e) {
+ } catch (final NoSuchNotificationQueue e) {
log.error(String.format("Failed to retrieve notification queue %s:%s", DefaultPaymentService.SERVICE_NAME, getQueueName()));
return false;
- } catch (IOException e) {
- log.error(String.format("Failed to serialize notificationQueue event for object %s, objectId %s", objectId));
+ } catch (final IOException e) {
+ log.error(String.format("Failed to serialize notificationQueue event for objectId %s", objectId));
return false;
}
return true;
}
- protected InternalCallContext createCallContextFromPaymentId(final ObjectType objectType, final UUID objectId) {
- return internalCallContextFactory.createInternalCallContext(objectId, objectType, PAYMENT_RETRY_SERVICE, CallOrigin.INTERNAL, UserType.SYSTEM, null);
+ protected InternalCallContext createCallContextFromPaymentId(final ObjectType objectType, final UUID objectId, final Long tenantRecordId) {
+ return internalCallContextFactory.createInternalCallContext(objectId, objectType, PAYMENT_RETRY_SERVICE, CallOrigin.INTERNAL, UserType.SYSTEM, null, tenantRecordId);
}
public abstract String getQueueName();
diff --git a/payment/src/test/java/org/killbill/billing/payment/core/sm/TestRetryablePayment.java b/payment/src/test/java/org/killbill/billing/payment/core/sm/TestRetryablePayment.java
index 110bb1b..bc178c9 100644
--- a/payment/src/test/java/org/killbill/billing/payment/core/sm/TestRetryablePayment.java
+++ b/payment/src/test/java/org/killbill/billing/payment/core/sm/TestRetryablePayment.java
@@ -1,7 +1,8 @@
/*
- * Copyright 2014 Groupon, Inc
+ * Copyright 2014-2015 Groupon, Inc
+ * Copyright 2014-2015 The Billing Project, LLC
*
- * Groupon 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:
*
@@ -52,6 +53,7 @@ import org.killbill.billing.payment.provider.MockPaymentRoutingProviderPlugin;
import org.killbill.billing.payment.retry.BaseRetryService.RetryServiceScheduler;
import org.killbill.billing.routing.plugin.api.PaymentRoutingPluginApi;
import org.killbill.billing.tag.TagInternalApi;
+import org.killbill.billing.util.callcontext.InternalCallContextFactory;
import org.killbill.billing.util.dao.NonEntityDao;
import org.killbill.billing.util.globallocker.LockerType;
import org.killbill.commons.locker.GlobalLock;
@@ -105,6 +107,8 @@ public class TestRetryablePayment extends PaymentTestSuiteNoDB {
private PaymentStateMachineHelper paymentSMHelper;
@Inject
private RetryStateMachineHelper retrySMHelper;
+ @Inject
+ private InternalCallContextFactory internalCallContextFactory;
private Account account;
private DateTime utcNow;
@@ -195,13 +199,13 @@ public class TestRetryablePayment extends PaymentTestSuiteNoDB {
null,
tagApi,
paymentDao,
- nonEntityDao,
locker,
executor,
+ internalCallContextFactory,
runner,
retrySMHelper,
- clock,
- cacheControllerDispatcher);
+ clock
+ );
}
diff --git a/subscription/src/main/java/org/killbill/billing/subscription/api/svcs/DefaultSubscriptionInternalApi.java b/subscription/src/main/java/org/killbill/billing/subscription/api/svcs/DefaultSubscriptionInternalApi.java
index c6ca83b..77b50fc 100644
--- a/subscription/src/main/java/org/killbill/billing/subscription/api/svcs/DefaultSubscriptionInternalApi.java
+++ b/subscription/src/main/java/org/killbill/billing/subscription/api/svcs/DefaultSubscriptionInternalApi.java
@@ -1,7 +1,9 @@
/*
* Copyright 2010-2013 Ning, Inc.
+ * Copyright 2014-2015 Groupon, Inc
+ * Copyright 2014-2015 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:
*
@@ -27,7 +29,6 @@ import javax.annotation.Nullable;
import org.joda.time.DateTime;
import org.killbill.billing.ErrorCode;
-import org.killbill.billing.ObjectType;
import org.killbill.billing.callcontext.InternalCallContext;
import org.killbill.billing.callcontext.InternalTenantContext;
import org.killbill.billing.catalog.api.BillingActionPolicy;
@@ -63,9 +64,9 @@ import org.killbill.billing.subscription.engine.dao.SubscriptionDao;
import org.killbill.billing.subscription.engine.dao.model.SubscriptionBundleModelDao;
import org.killbill.billing.subscription.events.SubscriptionBaseEvent;
import org.killbill.billing.subscription.exceptions.SubscriptionBaseError;
-import org.killbill.billing.util.cache.Cachable.CacheType;
-import org.killbill.billing.util.cache.CacheControllerDispatcher;
-import org.killbill.billing.util.dao.NonEntityDao;
+import org.killbill.billing.util.callcontext.CallContext;
+import org.killbill.billing.util.callcontext.InternalCallContextFactory;
+import org.killbill.billing.util.callcontext.TenantContext;
import org.killbill.billing.util.entity.Pagination;
import org.killbill.billing.util.entity.dao.DefaultPaginationHelper.SourcePaginationBuilder;
import org.killbill.clock.Clock;
@@ -85,8 +86,7 @@ public class DefaultSubscriptionInternalApi extends SubscriptionApiBase implemen
private static final Logger log = LoggerFactory.getLogger(DefaultSubscriptionInternalApi.class);
private final AddonUtils addonUtils;
- private final NonEntityDao nonEntityDao;
- private final CacheControllerDispatcher controllerDispatcher;
+ private final InternalCallContextFactory internalCallContextFactory;
@Inject
public DefaultSubscriptionInternalApi(final SubscriptionDao dao,
@@ -94,12 +94,10 @@ public class DefaultSubscriptionInternalApi extends SubscriptionApiBase implemen
final Clock clock,
final CatalogService catalogService,
final AddonUtils addonUtils,
- final NonEntityDao nonEntityDao,
- final CacheControllerDispatcher controllerDispatcher) {
+ final InternalCallContextFactory internalCallContextFactory) {
super(dao, apiService, clock, catalogService);
this.addonUtils = addonUtils;
- this.nonEntityDao = nonEntityDao;
- this.controllerDispatcher = controllerDispatcher;
+ this.internalCallContextFactory = internalCallContextFactory;
}
@Override
@@ -128,15 +126,15 @@ public class DefaultSubscriptionInternalApi extends SubscriptionApiBase implemen
final DefaultSubscriptionBase baseSubscription = (DefaultSubscriptionBase) dao.getBaseSubscription(bundleId, context);
final DateTime bundleStartDate = getBundleStartDateWithSanity(bundleId, baseSubscription, plan, requestedDate, effectiveDate);
- final UUID tenantId = nonEntityDao.retrieveIdFromObject(context.getTenantRecordId(), ObjectType.TENANT, controllerDispatcher.getCacheController(CacheType.OBJECT_ID));
+ final CallContext callContext = internalCallContextFactory.createCallContext(context);
return apiService.createPlan(new SubscriptionBuilder()
.setId(UUID.randomUUID())
.setBundleId(bundleId)
.setCategory(plan.getProduct().getCategory())
.setBundleStartDate(bundleStartDate)
.setAlignStartDate(effectiveDate),
- plan, spec.getPhaseType(), realPriceList, requestedDate, effectiveDate, now, context.toCallContext(tenantId));
- } catch (CatalogApiException e) {
+ plan, spec.getPhaseType(), realPriceList, requestedDate, effectiveDate, now, callContext);
+ } catch (final CatalogApiException e) {
throw new SubscriptionBaseApiException(e);
}
}
@@ -211,11 +209,11 @@ public class DefaultSubscriptionInternalApi extends SubscriptionApiBase implemen
}
public static SubscriptionBaseBundle getActiveBundleForKeyNotException(final List<SubscriptionBaseBundle> existingBundles, final SubscriptionDao dao, final Clock clock, final InternalTenantContext context) {
- for (SubscriptionBaseBundle cur : existingBundles) {
+ for (final SubscriptionBaseBundle cur : existingBundles) {
final List<SubscriptionBase> subscriptions;
try {
subscriptions = dao.getSubscriptions(cur.getId(), ImmutableList.<SubscriptionBaseEvent>of(), context);
- for (SubscriptionBase s : subscriptions) {
+ for (final SubscriptionBase s : subscriptions) {
if (s.getCategory() == ProductCategory.ADD_ON) {
continue;
}
@@ -223,7 +221,7 @@ public class DefaultSubscriptionInternalApi extends SubscriptionApiBase implemen
return cur;
}
}
- } catch (CatalogApiException e) {
+ } catch (final CatalogApiException e) {
log.warn("Failed to get subscriptions, ", e);
return null;
}
@@ -232,9 +230,9 @@ public class DefaultSubscriptionInternalApi extends SubscriptionApiBase implemen
}
@Override
- public List<SubscriptionBase> getSubscriptionsForBundle(UUID bundleId,
+ public List<SubscriptionBase> getSubscriptionsForBundle(final UUID bundleId,
@Nullable final DryRunArguments dryRunArguments,
- InternalTenantContext context) throws SubscriptionBaseApiException {
+ final InternalTenantContext context) throws SubscriptionBaseApiException {
try {
final List<SubscriptionBaseEvent> outputDryRunEvents = new ArrayList<SubscriptionBaseEvent>();
@@ -247,7 +245,7 @@ public class DefaultSubscriptionInternalApi extends SubscriptionApiBase implemen
outputSubscriptions.addAll(result);
}
return createSubscriptionsForApiUse(outputSubscriptions);
- } catch (CatalogApiException e) {
+ } catch (final CatalogApiException e) {
throw new SubscriptionBaseApiException(e);
}
}
@@ -261,36 +259,33 @@ public class DefaultSubscriptionInternalApi extends SubscriptionApiBase implemen
result.put(bundleId, createSubscriptionsForApiUse(internalSubscriptions.get(bundleId)));
}
return result;
- } catch (CatalogApiException e) {
+ } catch (final CatalogApiException e) {
throw new SubscriptionBaseApiException(e);
}
}
@Override
- public SubscriptionBase getBaseSubscription(UUID bundleId,
- InternalTenantContext context) throws SubscriptionBaseApiException {
+ public SubscriptionBase getBaseSubscription(final UUID bundleId, final InternalTenantContext context) throws SubscriptionBaseApiException {
try {
final SubscriptionBase result = dao.getBaseSubscription(bundleId, context);
if (result == null) {
throw new SubscriptionBaseApiException(ErrorCode.SUB_GET_NO_SUCH_BASE_SUBSCRIPTION, bundleId);
}
return createSubscriptionForApiUse(result);
- } catch (CatalogApiException e) {
+ } catch (final CatalogApiException e) {
throw new SubscriptionBaseApiException(e);
}
}
@Override
-
- public SubscriptionBase getSubscriptionFromId(UUID id,
- InternalTenantContext context) throws SubscriptionBaseApiException {
+ public SubscriptionBase getSubscriptionFromId(final UUID id, final InternalTenantContext context) throws SubscriptionBaseApiException {
try {
final SubscriptionBase result = dao.getSubscriptionFromId(id, context);
if (result == null) {
throw new SubscriptionBaseApiException(ErrorCode.SUB_INVALID_SUBSCRIPTION_ID, id);
}
return createSubscriptionForApiUse(result);
- } catch (CatalogApiException e) {
+ } catch (final CatalogApiException e) {
throw new SubscriptionBaseApiException(e);
}
}
@@ -310,15 +305,14 @@ public class DefaultSubscriptionInternalApi extends SubscriptionApiBase implemen
}
@Override
- public void setChargedThroughDate(UUID subscriptionId,
- DateTime chargedThruDate, InternalCallContext context) throws SubscriptionBaseApiException {
+ public void setChargedThroughDate(final UUID subscriptionId, final DateTime chargedThruDate, final InternalCallContext context) throws SubscriptionBaseApiException {
try {
final DefaultSubscriptionBase subscription = (DefaultSubscriptionBase) dao.getSubscriptionFromId(subscriptionId, context);
final SubscriptionBuilder builder = new SubscriptionBuilder(subscription)
.setChargedThroughDate(chargedThruDate);
dao.updateChargedThroughDate(new DefaultSubscriptionBase(builder), context);
- } catch (CatalogApiException e) {
+ } catch (final CatalogApiException e) {
throw new SubscriptionBaseApiException(e);
}
}
@@ -376,7 +370,7 @@ public class DefaultSubscriptionInternalApi extends SubscriptionApiBase implemen
result.add(status);
}
return result;
- } catch (CatalogApiException e) {
+ } catch (final CatalogApiException e) {
throw new SubscriptionBaseApiException(e);
}
@@ -391,7 +385,7 @@ public class DefaultSubscriptionInternalApi extends SubscriptionApiBase implemen
@Nullable final DryRunArguments dryRunArguments,
final List<SubscriptionBaseEvent> outputDryRunEvents,
final List<SubscriptionBase> outputSubscriptions,
- InternalTenantContext context) throws SubscriptionBaseApiException {
+ final InternalTenantContext context) throws SubscriptionBaseApiException {
if (dryRunArguments == null || dryRunArguments.getAction() == null) {
return;
}
@@ -404,7 +398,7 @@ public class DefaultSubscriptionInternalApi extends SubscriptionApiBase implemen
final Catalog catalog = catalogService.getFullCatalog(context);
final Plan plan = (inputSpec != null && inputSpec.getProductName() != null && inputSpec.getBillingPeriod() != null) ?
catalog.findPlan(inputSpec.getProductName(), inputSpec.getBillingPeriod(), realPriceList, utcNow) : null;
- final UUID tenantId = nonEntityDao.retrieveIdFromObject(context.getTenantRecordId(), ObjectType.TENANT, controllerDispatcher.getCacheController(CacheType.OBJECT_ID));
+ final TenantContext tenantContext = internalCallContextFactory.createTenantContext(context);
if (dryRunArguments != null) {
switch (dryRunArguments.getAction()) {
@@ -415,7 +409,7 @@ public class DefaultSubscriptionInternalApi extends SubscriptionApiBase implemen
final DateTime bundleStartDate = getBundleStartDateWithSanity(bundleId, baseSubscription, plan, startEffectiveDate, startEffectiveDate);
final UUID subscriptionId = UUID.randomUUID();
dryRunEvents = apiService.getEventsOnCreation(bundleId, subscriptionId, startEffectiveDate, bundleStartDate, 1L, plan, inputSpec.getPhaseType(), realPriceList,
- utcNow, startEffectiveDate, utcNow, false, context.toTenantContext(tenantId));
+ utcNow, startEffectiveDate, utcNow, false, tenantContext);
final SubscriptionBuilder builder = new SubscriptionBuilder()
.setId(subscriptionId)
.setBundleId(bundleId)
@@ -436,12 +430,12 @@ public class DefaultSubscriptionInternalApi extends SubscriptionApiBase implemen
final PlanChangeResult planChangeResult = apiService.getPlanChangeResult(subscriptionForChange,
dryRunArguments.getPlanPhaseSpecifier().getProductName(),
dryRunArguments.getPlanPhaseSpecifier().getBillingPeriod(),
- dryRunArguments.getPlanPhaseSpecifier().getPriceListName(), utcNow, context.toTenantContext(tenantId));
+ dryRunArguments.getPlanPhaseSpecifier().getPriceListName(), utcNow, tenantContext);
policy = planChangeResult.getPolicy();
}
changeEffectiveDate = subscriptionForChange.getPlanChangeEffectiveDate(policy);
}
- dryRunEvents = apiService.getEventsOnChangePlan(subscriptionForChange, plan, realPriceList, utcNow, changeEffectiveDate, utcNow, true, context.toTenantContext(tenantId));
+ dryRunEvents = apiService.getEventsOnChangePlan(subscriptionForChange, plan, realPriceList, utcNow, changeEffectiveDate, utcNow, true, tenantContext);
break;
case STOP_BILLING:
@@ -461,14 +455,14 @@ public class DefaultSubscriptionInternalApi extends SubscriptionApiBase implemen
}
cancelEffectiveDate = subscriptionForCancellation.getPlanChangeEffectiveDate(policy);
}
- dryRunEvents = apiService.getEventsOnCancelPlan(subscriptionForCancellation, utcNow, cancelEffectiveDate, utcNow, true, context.toTenantContext(tenantId));
+ dryRunEvents = apiService.getEventsOnCancelPlan(subscriptionForCancellation, utcNow, cancelEffectiveDate, utcNow, true, tenantContext);
break;
default:
throw new IllegalArgumentException("Unexpected dryRunArguments action " + dryRunArguments.getAction());
}
}
- } catch (CatalogApiException e) {
+ } catch (final CatalogApiException e) {
throw new SubscriptionBaseApiException(e);
}
if (dryRunEvents != null && !dryRunEvents.isEmpty()) {
@@ -514,7 +508,7 @@ public class DefaultSubscriptionInternalApi extends SubscriptionApiBase implemen
return ImmutableList.<EffectiveSubscriptionInternalEvent>copyOf(Collections2.transform(transitions, new Function<SubscriptionBaseTransition, EffectiveSubscriptionInternalEvent>() {
@Override
@Nullable
- public EffectiveSubscriptionInternalEvent apply(@Nullable SubscriptionBaseTransition input) {
+ public EffectiveSubscriptionInternalEvent apply(@Nullable final SubscriptionBaseTransition input) {
return new DefaultEffectiveSubscriptionEvent((SubscriptionBaseTransitionData) input, ((DefaultSubscriptionBase) subscription).getAlignStartDate(), null, context.getAccountRecordId(), context.getTenantRecordId());
}
}));
diff --git a/subscription/src/main/java/org/killbill/billing/subscription/engine/core/DefaultSubscriptionBaseService.java b/subscription/src/main/java/org/killbill/billing/subscription/engine/core/DefaultSubscriptionBaseService.java
index d91b31f..a1dcae8 100644
--- a/subscription/src/main/java/org/killbill/billing/subscription/engine/core/DefaultSubscriptionBaseService.java
+++ b/subscription/src/main/java/org/killbill/billing/subscription/engine/core/DefaultSubscriptionBaseService.java
@@ -1,7 +1,7 @@
/*
* Copyright 2010-2013 Ning, Inc.
- * Copyright 2014 Groupon, Inc
- * Copyright 2014 The Billing Project, LLC
+ * Copyright 2014-2015 Groupon, Inc
+ * Copyright 2014-2015 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
@@ -21,7 +21,6 @@ package org.killbill.billing.subscription.engine.core;
import java.util.UUID;
import org.joda.time.DateTime;
-import org.killbill.billing.ObjectType;
import org.killbill.billing.callcontext.InternalCallContext;
import org.killbill.billing.catalog.api.CatalogApiException;
import org.killbill.billing.catalog.api.Product;
@@ -37,7 +36,6 @@ import org.killbill.billing.subscription.api.SubscriptionBaseService;
import org.killbill.billing.subscription.api.user.DefaultEffectiveSubscriptionEvent;
import org.killbill.billing.subscription.api.user.DefaultSubscriptionBase;
import org.killbill.billing.subscription.api.user.SubscriptionBaseTransitionData;
-import org.killbill.billing.subscription.engine.addon.AddonUtils;
import org.killbill.billing.subscription.engine.dao.SubscriptionDao;
import org.killbill.billing.subscription.events.SubscriptionBaseEvent;
import org.killbill.billing.subscription.events.SubscriptionBaseEvent.EventType;
@@ -45,13 +43,10 @@ import org.killbill.billing.subscription.events.phase.PhaseEvent;
import org.killbill.billing.subscription.events.phase.PhaseEventData;
import org.killbill.billing.subscription.events.user.ApiEvent;
import org.killbill.billing.subscription.exceptions.SubscriptionBaseError;
-import org.killbill.billing.util.cache.Cachable.CacheType;
-import org.killbill.billing.util.cache.CacheControllerDispatcher;
import org.killbill.billing.util.callcontext.CallContext;
import org.killbill.billing.util.callcontext.CallOrigin;
import org.killbill.billing.util.callcontext.InternalCallContextFactory;
import org.killbill.billing.util.callcontext.UserType;
-import org.killbill.billing.util.dao.NonEntityDao;
import org.killbill.bus.api.PersistentBus;
import org.killbill.bus.api.PersistentBus.EventBusException;
import org.killbill.clock.Clock;
@@ -81,17 +76,13 @@ public class DefaultSubscriptionBaseService implements EventListener, Subscripti
private final InternalCallContextFactory internalCallContextFactory;
private NotificationQueue subscriptionEventQueue;
private final SubscriptionBaseApiService apiService;
- private final NonEntityDao nonEntityDao;
- private final CacheControllerDispatcher controllerDispatcher;
@Inject
public DefaultSubscriptionBaseService(final Clock clock, final SubscriptionDao dao, final PlanAligner planAligner,
final PersistentBus eventBus,
final NotificationQueueService notificationQueueService,
final InternalCallContextFactory internalCallContextFactory,
- final SubscriptionBaseApiService apiService,
- final NonEntityDao nonEntityDao,
- final CacheControllerDispatcher controllerDispatcher) {
+ final SubscriptionBaseApiService apiService) {
this.clock = clock;
this.dao = dao;
this.planAligner = planAligner;
@@ -99,8 +90,6 @@ public class DefaultSubscriptionBaseService implements EventListener, Subscripti
this.notificationQueueService = notificationQueueService;
this.internalCallContextFactory = internalCallContextFactory;
this.apiService = apiService;
- this.nonEntityDao = nonEntityDao;
- this.controllerDispatcher = controllerDispatcher;
}
@Override
@@ -135,7 +124,7 @@ public class DefaultSubscriptionBaseService implements EventListener, Subscripti
subscriptionEventQueue = notificationQueueService.createNotificationQueue(SUBSCRIPTION_SERVICE_NAME,
NOTIFICATION_QUEUE_NAME,
queueHandler);
- } catch (NotificationQueueAlreadyExists e) {
+ } catch (final NotificationQueueAlreadyExists e) {
throw new RuntimeException(e);
}
}
@@ -159,7 +148,6 @@ public class DefaultSubscriptionBaseService implements EventListener, Subscripti
return;
}
-
try {
final DefaultSubscriptionBase subscription = (DefaultSubscriptionBase) dao.getSubscriptionFromId(event.getSubscriptionId(), context);
if (subscription == null) {
@@ -178,8 +166,8 @@ public class DefaultSubscriptionBaseService implements EventListener, Subscripti
if (event.getType() == EventType.PHASE) {
onPhaseEvent(subscription, context);
} else if (event.getType() == EventType.API_USER && subscription.getCategory() == ProductCategory.BASE) {
- final UUID tenantId = nonEntityDao.retrieveIdFromObject(context.getTenantRecordId(), ObjectType.TENANT, controllerDispatcher.getCacheController(CacheType.OBJECT_ID));
- theRealSeqId = onBasePlanEvent(subscription, (ApiEvent) event, context.toCallContext(tenantId));
+ final CallContext callContext = internalCallContextFactory.createCallContext(context);
+ theRealSeqId = onBasePlanEvent(subscription, (ApiEvent) event, callContext);
}
final SubscriptionBaseTransitionData transition = (subscription.getTransitionFromEvent(event, theRealSeqId));
@@ -187,9 +175,9 @@ public class DefaultSubscriptionBaseService implements EventListener, Subscripti
context.getUserToken(),
context.getAccountRecordId(), context.getTenantRecordId());
eventBus.post(busEvent);
- } catch (EventBusException e) {
+ } catch (final EventBusException e) {
log.warn("Failed to post subscription event " + event, e);
- } catch (CatalogApiException e) {
+ } catch (final CatalogApiException e) {
log.warn("Failed to post subscription event " + event, e);
}
}
@@ -205,7 +193,7 @@ public class DefaultSubscriptionBaseService implements EventListener, Subscripti
if (nextPhaseEvent != null) {
dao.createNextPhaseEvent(subscription, nextPhaseEvent, context);
}
- } catch (SubscriptionBaseError e) {
+ } catch (final SubscriptionBaseError e) {
log.error(String.format("Failed to insert next phase for subscription %s", subscription.getId()), e);
}
}
diff --git a/util/src/main/java/org/killbill/billing/util/cache/AccountRecordIdCacheLoader.java b/util/src/main/java/org/killbill/billing/util/cache/AccountRecordIdCacheLoader.java
index 7562ea9..87fff3b 100644
--- a/util/src/main/java/org/killbill/billing/util/cache/AccountRecordIdCacheLoader.java
+++ b/util/src/main/java/org/killbill/billing/util/cache/AccountRecordIdCacheLoader.java
@@ -1,7 +1,9 @@
/*
* Copyright 2010-2013 Ning, Inc.
+ * Copyright 2014-2015 Groupon, Inc
+ * Copyright 2014-2015 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:
*
@@ -21,8 +23,6 @@ import java.util.UUID;
import javax.inject.Inject;
import javax.inject.Singleton;
-import org.skife.jdbi.v2.IDBI;
-
import org.killbill.billing.ObjectType;
import org.killbill.billing.util.cache.Cachable.CacheType;
import org.killbill.billing.util.dao.NonEntityDao;
@@ -47,6 +47,6 @@ public class AccountRecordIdCacheLoader extends BaseIdCacheLoader implements Cac
@Override
protected Object doRetrieveOperation(final String rawKey, final ObjectType objectType) {
- return nonEntityDao.retrieveAccountRecordIdFromObject(UUID.fromString(rawKey), objectType, null);
+ return nonEntityDao.retrieveAccountRecordIdFromObject(UUID.fromString(rawKey), objectType, null);
}
}
diff --git a/util/src/main/java/org/killbill/billing/util/cache/RecordIdCacheLoader.java b/util/src/main/java/org/killbill/billing/util/cache/RecordIdCacheLoader.java
index 6c78335..889057b 100644
--- a/util/src/main/java/org/killbill/billing/util/cache/RecordIdCacheLoader.java
+++ b/util/src/main/java/org/killbill/billing/util/cache/RecordIdCacheLoader.java
@@ -1,7 +1,9 @@
/*
* Copyright 2010-2012 Ning, Inc.
+ * Copyright 2014-2015 Groupon, Inc
+ * Copyright 2014-2015 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:
*
@@ -21,8 +23,6 @@ import java.util.UUID;
import javax.inject.Inject;
import javax.inject.Singleton;
-import org.skife.jdbi.v2.IDBI;
-
import org.killbill.billing.ObjectType;
import org.killbill.billing.util.cache.Cachable.CacheType;
import org.killbill.billing.util.dao.NonEntityDao;
@@ -35,7 +35,7 @@ public class RecordIdCacheLoader extends BaseIdCacheLoader implements CacheLoade
private final NonEntityDao nonEntityDao;
@Inject
- public RecordIdCacheLoader(final IDBI dbi, final NonEntityDao nonEntityDao) {
+ public RecordIdCacheLoader(final NonEntityDao nonEntityDao) {
super();
this.nonEntityDao = nonEntityDao;
}
diff --git a/util/src/main/java/org/killbill/billing/util/cache/TenantRecordIdCacheLoader.java b/util/src/main/java/org/killbill/billing/util/cache/TenantRecordIdCacheLoader.java
index fe3d2f4..fd0501b 100644
--- a/util/src/main/java/org/killbill/billing/util/cache/TenantRecordIdCacheLoader.java
+++ b/util/src/main/java/org/killbill/billing/util/cache/TenantRecordIdCacheLoader.java
@@ -1,7 +1,9 @@
/*
* Copyright 2010-2013 Ning, Inc.
+ * Copyright 2014-2015 Groupon, Inc
+ * Copyright 2014-2015 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:
*
@@ -21,8 +23,6 @@ import java.util.UUID;
import javax.inject.Inject;
import javax.inject.Singleton;
-import org.skife.jdbi.v2.IDBI;
-
import org.killbill.billing.ObjectType;
import org.killbill.billing.util.cache.Cachable.CacheType;
import org.killbill.billing.util.dao.NonEntityDao;
diff --git a/util/src/main/java/org/killbill/billing/util/callcontext/InternalCallContextFactory.java b/util/src/main/java/org/killbill/billing/util/callcontext/InternalCallContextFactory.java
index 71a1fe9..171aabb 100644
--- a/util/src/main/java/org/killbill/billing/util/callcontext/InternalCallContextFactory.java
+++ b/util/src/main/java/org/killbill/billing/util/callcontext/InternalCallContextFactory.java
@@ -1,7 +1,9 @@
/*
* Copyright 2010-2012 Ning, Inc.
+ * Copyright 2014-2015 Groupon, Inc
+ * Copyright 2014-2015 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:
*
@@ -48,6 +50,24 @@ public class InternalCallContextFactory {
this.cacheControllerDispatcher = cacheControllerDispatcher;
}
+ //
+ // Create contexts from internal contexts
+ //
+
+ public TenantContext createTenantContext(final InternalTenantContext context) {
+ final UUID tenantId = getTenantIdSafe(context);
+ return context.toTenantContext(tenantId);
+ }
+
+ public CallContext createCallContext(final InternalCallContext context) {
+ final UUID tenantId = getTenantIdSafe(context);
+ return context.toCallContext(tenantId);
+ }
+
+ //
+ // Create InternalTenantContext
+ //
+
/**
* Create an internal tenant callcontext from a tenant callcontext
* <p/>
@@ -59,38 +79,18 @@ public class InternalCallContextFactory {
*/
public InternalTenantContext createInternalTenantContext(final TenantContext context) {
// If tenant id is null, this will default to the default tenant record id (multi-tenancy disabled)
- final Long tenantRecordId = getTenantRecordId(context);
+ final Long tenantRecordId = getTenantRecordIdSafe(context);
return createInternalTenantContext(tenantRecordId, null);
}
- /**
- * Create an internal tenant callcontext
- *
- * @param tenantRecordId tenant_record_id (cannot be null)
- * @param accountRecordId account_record_id (cannot be null for INSERT operations)
- * @return internal tenant callcontext
- */
- public InternalTenantContext createInternalTenantContext(final Long tenantRecordId, @Nullable final Long accountRecordId) {
- //Preconditions.checkNotNull(tenantRecordId, "tenantRecordId cannot be null");
- return new InternalTenantContext(tenantRecordId, accountRecordId);
- }
-
public InternalTenantContext createInternalTenantContext(final UUID accountId, final TenantContext context) {
- final Long tenantRecordId = getTenantRecordId(context);
- final Long accountRecordId = getAccountRecordId(accountId, ObjectType.ACCOUNT);
- return new InternalTenantContext(tenantRecordId, accountRecordId);
+ return createInternalTenantContext(accountId, ObjectType.ACCOUNT, context);
}
public InternalTenantContext createInternalTenantContext(final UUID accountId, final InternalTenantContext context) {
final Long tenantRecordId = context.getTenantRecordId();
- final Long accountRecordId = getAccountRecordId(accountId, ObjectType.ACCOUNT);
- return new InternalTenantContext(tenantRecordId, accountRecordId);
- }
-
- public InternalTenantContext createInternalTenantContext(final UUID accountId, final UUID objectId, final ObjectType objectType) {
- final Long tenantRecordId = getTenantRecordId(objectId, objectType);
- final Long accountRecordId = getAccountRecordId(accountId, ObjectType.ACCOUNT);
- return new InternalTenantContext(tenantRecordId, accountRecordId);
+ final Long accountRecordId = getAccountRecordIdSafe(accountId, ObjectType.ACCOUNT, context.getTenantRecordId());
+ return createInternalTenantContext(tenantRecordId, accountRecordId);
}
/**
@@ -104,34 +104,30 @@ public class InternalCallContextFactory {
public InternalTenantContext createInternalTenantContext(final UUID objectId, final ObjectType objectType, final TenantContext context) {
// The callcontext may come from a user API - for security, check we're not doing cross-tenants operations
//final Long tenantRecordIdFromObject = retrieveTenantRecordIdFromObject(objectId, objectType);
- //final Long tenantRecordIdFromContext = getTenantRecordId(callcontext);
+ //final Long tenantRecordIdFromContext = getTenantRecordIdSafe(callcontext);
//Preconditions.checkState(tenantRecordIdFromContext.equals(tenantRecordIdFromObject),
// "tenant of the pointed object (%s) and the callcontext (%s) don't match!", tenantRecordIdFromObject, tenantRecordIdFromContext);
- final Long tenantRecordId = getTenantRecordId(context);
- final Long accountRecordId = getAccountRecordId(objectId, objectType);
+ final Long tenantRecordId = getTenantRecordIdSafe(context);
+ final Long accountRecordId = getAccountRecordIdSafe(objectId, objectType, context);
return createInternalTenantContext(tenantRecordId, accountRecordId);
}
/**
- * Create an internal call callcontext from a call callcontext, and retrieving the account_record_id from another table
+ * Create an internal tenant callcontext
*
- * @param objectId the id of the row in the table pointed by object type where to look for account_record_id
- * @param objectType the object type pointed by this objectId
- * @param context original call callcontext
- * @return internal call callcontext from callcontext, with a non null account_record_id (if found)
+ * @param tenantRecordId tenant_record_id (cannot be null)
+ * @param accountRecordId account_record_id (cannot be null for INSERT operations)
+ * @return internal tenant callcontext
*/
- public InternalCallContext createInternalCallContext(final UUID objectId, final ObjectType objectType, final CallContext context) {
- // The callcontext may come from a user API - for security, check we're not doing cross-tenants operations
- //final Long tenantRecordIdFromObject = retrieveTenantRecordIdFromObject(objectId, objectType);
- //final Long tenantRecordIdFromContext = getTenantRecordId(callcontext);
- //Preconditions.checkState(tenantRecordIdFromContext.equals(tenantRecordIdFromObject),
- // "tenant of the pointed object (%s) and the callcontext (%s) don't match!", tenantRecordIdFromObject, tenantRecordIdFromContext);
-
- return createInternalCallContext(objectId, objectType, context.getUserName(), context.getCallOrigin(),
- context.getUserType(), context.getUserToken(), context.getReasonCode(), context.getComments(),
- context.getCreatedDate(), context.getUpdatedDate());
+ public InternalTenantContext createInternalTenantContext(final Long tenantRecordId, @Nullable final Long accountRecordId) {
+ //Preconditions.checkNotNull(tenantRecordId, "tenantRecordId cannot be null");
+ return new InternalTenantContext(tenantRecordId, accountRecordId);
}
+ //
+ // Create InternalCallContext
+ //
+
/**
* Create an internal call callcontext using an existing account to retrieve tenant and account record ids
* <p/>
@@ -142,50 +138,35 @@ public class InternalCallContextFactory {
* @return internal call callcontext
*/
public InternalCallContext createInternalCallContext(final UUID accountId, final CallContext context) {
- return createInternalCallContext(accountId, ObjectType.ACCOUNT, context.getUserName(), context.getCallOrigin(),
- context.getUserType(), context.getUserToken(), context.getReasonCode(), context.getComments(),
- context.getCreatedDate(), context.getUpdatedDate());
- }
-
- /**
- * Create an internal call callcontext using an existing account to retrieve tenant and account record ids
- *
- * @param accountId account id
- * @param userName user name
- * @param callOrigin call origin
- * @param userType user type
- * @param userToken user token, if any
- * @return internal call callcontext
- */
- public InternalCallContext createInternalCallContext(final UUID accountId, final String userName, final CallOrigin callOrigin,
- final UserType userType, @Nullable final UUID userToken) {
- return createInternalCallContext(accountId, ObjectType.ACCOUNT, userName, callOrigin, userType, userToken);
+ return createInternalCallContext(accountId, ObjectType.ACCOUNT, context);
}
/**
- * Create an internal call callcontext using an existing object to retrieve tenant and account record ids
+ * Create an internal call callcontext from a call callcontext, and retrieving the account_record_id from another table
*
* @param objectId the id of the row in the table pointed by object type where to look for account_record_id
* @param objectType the object type pointed by this objectId
- * @param userName user name
- * @param callOrigin call origin
- * @param userType user type
- * @param userToken user token, if any
- * @return internal call callcontext
+ * @param context original call callcontext
+ * @return internal call callcontext from callcontext, with a non null account_record_id (if found)
*/
- public InternalCallContext createInternalCallContext(final UUID objectId, final ObjectType objectType, final String userName,
- final CallOrigin callOrigin, final UserType userType, @Nullable final UUID userToken) {
- return createInternalCallContext(objectId, objectType, userName, callOrigin, userType, userToken, null, null, clock.getUTCNow(), clock.getUTCNow());
+ public InternalCallContext createInternalCallContext(final UUID objectId, final ObjectType objectType, final CallContext context) {
+ // The callcontext may come from a user API - for security, check we're not doing cross-tenants operations
+ //final Long tenantRecordIdFromObject = retrieveTenantRecordIdFromObject(objectId, objectType);
+ //final Long tenantRecordIdFromContext = getTenantRecordIdSafe(callcontext);
+ //Preconditions.checkState(tenantRecordIdFromContext.equals(tenantRecordIdFromObject),
+ // "tenant of the pointed object (%s) and the callcontext (%s) don't match!", tenantRecordIdFromObject, tenantRecordIdFromContext);
+
+ return createInternalCallContext(objectId, objectType, context.getUserName(), context.getCallOrigin(),
+ context.getUserType(), context.getUserToken(), context.getReasonCode(), context.getComments(),
+ context.getCreatedDate(), context.getUpdatedDate(), context);
}
+ // Used by the payment retry service
public InternalCallContext createInternalCallContext(final UUID objectId, final ObjectType objectType, final String userName,
- final CallOrigin callOrigin, final UserType userType, @Nullable final UUID userToken,
- @Nullable final String reasonCode, @Nullable final String comment, final DateTime createdDate,
- final DateTime updatedDate) {
- final Long tenantRecordId = nonEntityDao.retrieveTenantRecordIdFromObject(objectId, objectType, cacheControllerDispatcher.getCacheController(CacheType.TENANT_RECORD_ID));
- final Long accountRecordId = getAccountRecordId(objectId, objectType);
+ final CallOrigin callOrigin, final UserType userType, @Nullable final UUID userToken, final Long tenantRecordId) {
+ final Long accountRecordId = getAccountRecordIdSafe(objectId, objectType, tenantRecordId);
return createInternalCallContext(tenantRecordId, accountRecordId, userName, callOrigin, userType, userToken,
- reasonCode, comment, createdDate, updatedDate);
+ null, null, clock.getUTCNow(), clock.getUTCNow());
}
/**
@@ -207,17 +188,6 @@ public class InternalCallContextFactory {
clock.getUTCNow(), clock.getUTCNow());
}
- private InternalCallContext createInternalCallContext(@Nullable final Long tenantRecordId, final Long accountRecordId, final String userName,
- final CallOrigin callOrigin, final UserType userType, @Nullable final UUID userToken,
- @Nullable final String reasonCode, @Nullable final String comment, final DateTime createdDate,
- final DateTime updatedDate) {
- //Preconditions.checkNotNull(accountRecordId, "accountRecordId cannot be null");
- final Long nonNulTenantRecordId = Objects.firstNonNull(tenantRecordId, INTERNAL_TENANT_RECORD_ID);
-
- return new InternalCallContext(nonNulTenantRecordId, accountRecordId, userToken, userName, callOrigin, userType, reasonCode, comment,
- createdDate, updatedDate);
- }
-
/**
* Create an internal call callcontext without populating the account record id
* <p/>
@@ -229,7 +199,7 @@ public class InternalCallContextFactory {
*/
public InternalCallContext createInternalCallContext(final CallContext context) {
// If tenant id is null, this will default to the default tenant record id (multi-tenancy disabled)
- final Long tenantRecordId = getTenantRecordId(context);
+ final Long tenantRecordId = getTenantRecordIdSafe(context);
return new InternalCallContext(tenantRecordId, null, context);
}
@@ -240,32 +210,119 @@ public class InternalCallContextFactory {
context.getCreatedDate(), context.getUpdatedDate());
}
- // Used when we need to re-hydrate the callcontext with the tenant_record_id and account_record_id (when claiming bus events)
- public InternalCallContext createInternalCallContext(final Long tenantRecordId, final Long accountRecordId, final InternalCallContext context) {
- return new InternalCallContext(tenantRecordId, accountRecordId, context.getUserToken(), context.getCreatedBy(),
- context.getCallOrigin(), context.getContextUserType(), context.getReasonCode(), context.getComments(),
- context.getCreatedDate(), context.getUpdatedDate());
+ private InternalCallContext createInternalCallContext(final UUID objectId, final ObjectType objectType, final String userName,
+ final CallOrigin callOrigin, final UserType userType, @Nullable final UUID userToken,
+ @Nullable final String reasonCode, @Nullable final String comment, final DateTime createdDate,
+ final DateTime updatedDate, final TenantContext tenantContext) {
+ final Long tenantRecordId = getTenantRecordIdSafe(objectId, objectType, tenantContext);
+ final Long accountRecordId = getAccountRecordIdSafe(objectId, objectType, tenantContext);
+ return createInternalCallContext(tenantRecordId, accountRecordId, userName, callOrigin, userType, userToken,
+ reasonCode, comment, createdDate, updatedDate);
}
- private Long getAccountRecordId(final UUID accountId) {
- return getAccountRecordId(accountId, ObjectType.ACCOUNT);
+ private InternalCallContext createInternalCallContext(@Nullable final Long tenantRecordId, final Long accountRecordId, final String userName,
+ final CallOrigin callOrigin, final UserType userType, @Nullable final UUID userToken,
+ @Nullable final String reasonCode, @Nullable final String comment, final DateTime createdDate,
+ final DateTime updatedDate) {
+ //Preconditions.checkNotNull(accountRecordId, "accountRecordId cannot be null");
+ final Long nonNulTenantRecordId = Objects.firstNonNull(tenantRecordId, INTERNAL_TENANT_RECORD_ID);
+
+ return new InternalCallContext(nonNulTenantRecordId, accountRecordId, userToken, userName, callOrigin, userType, reasonCode, comment,
+ createdDate, updatedDate);
}
- private Long getAccountRecordId(final UUID objectId, final ObjectType objectType) {
- return nonEntityDao.retrieveAccountRecordIdFromObject(objectId, objectType, cacheControllerDispatcher.getCacheController(CacheType.ACCOUNT_RECORD_ID));
+ //
+ // Safe NonEntityDao public wrappers
+ //
+
+ // Safe method to retrieve the account id from any object
+ public UUID getAccountId(final UUID objectId, final ObjectType objectType, final TenantContext context) {
+ final Long accountRecordId = getAccountRecordIdSafe(objectId, objectType, context);
+ if (accountRecordId != null) {
+ return nonEntityDao.retrieveIdFromObject(accountRecordId, ObjectType.ACCOUNT, cacheControllerDispatcher.getCacheController(CacheType.OBJECT_ID));
+ } else {
+ return null;
+ }
}
- private Long getTenantRecordId(final UUID objectId, final ObjectType objectType) {
- return nonEntityDao.retrieveTenantRecordIdFromObject(objectId, objectType, cacheControllerDispatcher.getCacheController(CacheType.TENANT_RECORD_ID));
+ // Safe method to retrieve the record id from any object (should only be used by DefaultRecordIdApi)
+ public Long getRecordIdFromObject(final UUID objectId, final ObjectType objectType, final TenantContext context) {
+ if (objectBelongsToTheRightTenant(objectId, objectType, context)) {
+ return nonEntityDao.retrieveRecordIdFromObject(objectId, objectType, cacheControllerDispatcher.getCacheController(CacheType.RECORD_ID));
+ } else {
+ return null;
+ }
+ }
+
+ //
+ // Safe NonEntityDao private wrappers
+ //
+
+ private Long getAccountRecordIdSafe(final UUID objectId, final ObjectType objectType, final TenantContext context) {
+ if (objectBelongsToTheRightTenant(objectId, objectType, context)) {
+ return getAccountRecordIdUnsafe(objectId, objectType);
+ } else {
+ return null;
+ }
+ }
+
+ private Long getAccountRecordIdSafe(final UUID objectId, final ObjectType objectType, final Long tenantRecordId) {
+ if (objectBelongsToTheRightTenant(objectId, objectType, tenantRecordId)) {
+ return getAccountRecordIdUnsafe(objectId, objectType);
+ } else {
+ return null;
+ }
+ }
+
+ private Long getTenantRecordIdSafe(final UUID objectId, final ObjectType objectType, final TenantContext context) {
+ if (objectBelongsToTheRightTenant(objectId, objectType, context)) {
+ return getTenantRecordIdUnsafe(objectId, objectType);
+ } else {
+ return null;
+ }
}
- private Long getTenantRecordId(final TenantContext context) {
+ private Long getTenantRecordIdSafe(final TenantContext context) {
+ return getTenantRecordIdSafe(context.getTenantId());
+ }
+
+ private Long getTenantRecordIdSafe(final UUID tenantId) {
// Default to single default tenant (e.g. single tenant mode)
// TODO Extract this convention (e.g. BusinessAnalyticsBase needs to know about it)
- if (context.getTenantId() == null) {
+ if (tenantId == null) {
return INTERNAL_TENANT_RECORD_ID;
} else {
- return nonEntityDao.retrieveTenantRecordIdFromObject(context.getTenantId(), ObjectType.TENANT, cacheControllerDispatcher.getCacheController(CacheType.TENANT_RECORD_ID));
+ return getTenantRecordIdUnsafe(tenantId, ObjectType.TENANT);
}
}
+
+ private UUID getTenantIdSafe(final InternalTenantContext context) {
+ return nonEntityDao.retrieveIdFromObject(context.getTenantRecordId(), ObjectType.TENANT, cacheControllerDispatcher.getCacheController(CacheType.OBJECT_ID));
+ }
+
+ //
+ // In-code tenant checkers
+ //
+
+ private boolean objectBelongsToTheRightTenant(final UUID objectId, final ObjectType objectType, final TenantContext context) {
+ final Long realTenantRecordId = getTenantRecordIdSafe(context);
+ return objectBelongsToTheRightTenant(objectId, objectType, realTenantRecordId);
+ }
+
+ private boolean objectBelongsToTheRightTenant(final UUID objectId, final ObjectType objectType, final Long realTenantRecordId) {
+ final Long objectTenantRecordId = getTenantRecordIdUnsafe(objectId, objectType);
+ return realTenantRecordId != null && realTenantRecordId.equals(objectTenantRecordId);
+ }
+
+ //
+ // Unsafe methods - no context is validated
+ //
+
+ private Long getAccountRecordIdUnsafe(final UUID objectId, final ObjectType objectType) {
+ return nonEntityDao.retrieveAccountRecordIdFromObject(objectId, objectType, cacheControllerDispatcher.getCacheController(CacheType.ACCOUNT_RECORD_ID));
+ }
+
+ private Long getTenantRecordIdUnsafe(final UUID objectId, final ObjectType objectType) {
+ return nonEntityDao.retrieveTenantRecordIdFromObject(objectId, objectType, cacheControllerDispatcher.getCacheController(CacheType.TENANT_RECORD_ID));
+ }
}
diff --git a/util/src/main/java/org/killbill/billing/util/dao/NonEntityDao.java b/util/src/main/java/org/killbill/billing/util/dao/NonEntityDao.java
index e3dec90..600cb97 100644
--- a/util/src/main/java/org/killbill/billing/util/dao/NonEntityDao.java
+++ b/util/src/main/java/org/killbill/billing/util/dao/NonEntityDao.java
@@ -1,7 +1,9 @@
/*
* Copyright 2010-2013 Ning, Inc.
+ * Copyright 2014-2015 Groupon, Inc
+ * Copyright 2014-2015 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:
*
@@ -22,8 +24,8 @@ import javax.annotation.Nullable;
import org.killbill.billing.ObjectType;
import org.killbill.billing.util.cache.CacheController;
-import org.killbill.billing.util.entity.dao.EntitySqlDaoWrapperFactory;
+// This should only be used for internal operations (trusted code, not API), because the context will not be validated!
public interface NonEntityDao {
public Long retrieveRecordIdFromObject(final UUID objectId, final ObjectType objectType, @Nullable final CacheController<Object, Object> cache);
diff --git a/util/src/main/java/org/killbill/billing/util/recordid/DefaultRecordIdApi.java b/util/src/main/java/org/killbill/billing/util/recordid/DefaultRecordIdApi.java
index cc8a7ab..9fca345 100644
--- a/util/src/main/java/org/killbill/billing/util/recordid/DefaultRecordIdApi.java
+++ b/util/src/main/java/org/killbill/billing/util/recordid/DefaultRecordIdApi.java
@@ -1,7 +1,9 @@
/*
* Copyright 2010-2013 Ning, Inc.
+ * Copyright 2014-2015 Groupon, Inc
+ * Copyright 2014-2015 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:
*
@@ -22,25 +24,20 @@ import javax.inject.Inject;
import org.killbill.billing.ObjectType;
import org.killbill.billing.util.api.RecordIdApi;
-import org.killbill.billing.util.cache.Cachable.CacheType;
-import org.killbill.billing.util.cache.CacheControllerDispatcher;
+import org.killbill.billing.util.callcontext.InternalCallContextFactory;
import org.killbill.billing.util.callcontext.TenantContext;
-import org.killbill.billing.util.dao.NonEntityDao;
-public class DefaultRecordIdApi implements RecordIdApi {
+public class DefaultRecordIdApi implements RecordIdApi {
- private final NonEntityDao nonEntityDao;
- private final CacheControllerDispatcher cacheControllerDispatcher;
+ private final InternalCallContextFactory internalCallContextFactory;
@Inject
- public DefaultRecordIdApi(final NonEntityDao nonEntityDao, final CacheControllerDispatcher cacheControllerDispatcher) {
- this.nonEntityDao = nonEntityDao;
- this.cacheControllerDispatcher = cacheControllerDispatcher;
+ public DefaultRecordIdApi(final InternalCallContextFactory internalCallContextFactory) {
+ this.internalCallContextFactory = internalCallContextFactory;
}
-
@Override
public Long getRecordId(final UUID objectId, final ObjectType objectType, final TenantContext tenantContext) {
- return nonEntityDao.retrieveRecordIdFromObject(objectId, objectType, cacheControllerDispatcher.getCacheController(CacheType.RECORD_ID));
+ return internalCallContextFactory.getRecordIdFromObject(objectId, objectType, tenantContext);
}
}