killbill-uncached
Changes
analytics/src/test/java/com/ning/billing/analytics/api/user/TestDefaultAnalyticsUserApi.java 6(+5 -1)
entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/DefaultEntitlementDao.java 7(+5 -2)
entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/model/EntitlementEventModelDao.java 5(+5 -0)
entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/model/SubscriptionBundleModelDao.java 6(+6 -0)
entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/model/SubscriptionModelDao.java 6(+6 -0)
entitlement/src/test/java/com/ning/billing/entitlement/api/transfer/TestDefaultEntitlementTransferApi.java 5(+4 -1)
entitlement/src/test/java/com/ning/billing/entitlement/engine/dao/MockEntitlementDaoSql.java 6(+4 -2)
invoice/src/test/java/com/ning/billing/invoice/api/invoice/TestDefaultInvoicePaymentApi.java 9(+7 -2)
invoice/src/test/java/com/ning/billing/invoice/notification/TestNextBillingDateNotifier.java 18(+15 -3)
meter/src/test/java/com/ning/billing/meter/timeline/TestTimelineSourceEventAccumulator.java 5(+4 -1)
pom.xml 8(+8 -0)
server/src/main/resources/ehcache.xml 67(+67 -0)
server/src/test/resources/shiro.ini 3(+2 -1)
util/pom.xml 5(+5 -0)
util/src/main/java/com/ning/billing/util/entity/dao/EntitySqlDaoTransactionalJdbiWrapper.java 13(+11 -2)
util/src/main/java/com/ning/billing/util/entity/dao/EntitySqlDaoWrapperInvocationHandler.java 122(+107 -15)
util/src/main/java/com/ning/billing/util/notificationq/DefaultNotificationQueueService.java 11(+9 -2)
util/src/main/resources/ehcache.xml 67(+67 -0)
Details
diff --git a/account/src/main/java/com/ning/billing/account/dao/AccountEmailModelDao.java b/account/src/main/java/com/ning/billing/account/dao/AccountEmailModelDao.java
index 375ea7f..ec671b7 100644
--- a/account/src/main/java/com/ning/billing/account/dao/AccountEmailModelDao.java
+++ b/account/src/main/java/com/ning/billing/account/dao/AccountEmailModelDao.java
@@ -105,4 +105,9 @@ public class AccountEmailModelDao extends EntityBase implements EntityModelDao<A
public TableName getTableName() {
return TableName.ACCOUNT_EMAIL;
}
+
+ @Override
+ public TableName getHistoryTableName() {
+ return TableName.ACCOUNT_EMAIL_HISTORY;
+ }
}
diff --git a/account/src/main/java/com/ning/billing/account/dao/AccountModelDao.java b/account/src/main/java/com/ning/billing/account/dao/AccountModelDao.java
index 95e6aaa..e9266ed 100644
--- a/account/src/main/java/com/ning/billing/account/dao/AccountModelDao.java
+++ b/account/src/main/java/com/ning/billing/account/dao/AccountModelDao.java
@@ -318,4 +318,9 @@ public class AccountModelDao extends EntityBase implements EntityModelDao<Accoun
public TableName getTableName() {
return TableName.ACCOUNT;
}
+
+ @Override
+ public TableName getHistoryTableName() {
+ return TableName.ACCOUNT_HISTORY;
+ }
}
diff --git a/account/src/main/java/com/ning/billing/account/dao/DefaultAccountDao.java b/account/src/main/java/com/ning/billing/account/dao/DefaultAccountDao.java
index 18e2ac3..c5c0513 100644
--- a/account/src/main/java/com/ning/billing/account/dao/DefaultAccountDao.java
+++ b/account/src/main/java/com/ning/billing/account/dao/DefaultAccountDao.java
@@ -30,9 +30,12 @@ import com.ning.billing.account.api.AccountApiException;
import com.ning.billing.account.api.user.DefaultAccountChangeEvent;
import com.ning.billing.account.api.user.DefaultAccountCreationEvent;
import com.ning.billing.util.audit.ChangeType;
+import com.ning.billing.util.cache.CacheControllerDispatcher;
import com.ning.billing.util.callcontext.InternalCallContext;
import com.ning.billing.util.callcontext.InternalCallContextFactory;
import com.ning.billing.util.callcontext.InternalTenantContext;
+import com.ning.billing.util.clock.Clock;
+import com.ning.billing.util.dao.NonEntityDao;
import com.ning.billing.util.entity.EntityPersistenceException;
import com.ning.billing.util.entity.dao.EntityDaoBase;
import com.ning.billing.util.entity.dao.EntitySqlDao;
@@ -54,8 +57,9 @@ public class DefaultAccountDao extends EntityDaoBase<AccountModelDao, Account, A
private final InternalCallContextFactory internalCallContextFactory;
@Inject
- public DefaultAccountDao(final IDBI dbi, final InternalBus eventBus, final InternalCallContextFactory internalCallContextFactory) {
- super(new EntitySqlDaoTransactionalJdbiWrapper(dbi), AccountSqlDao.class);
+ public DefaultAccountDao(final IDBI dbi, final InternalBus eventBus, final Clock clock, final CacheControllerDispatcher cacheControllerDispatcher,
+ final InternalCallContextFactory internalCallContextFactory, final NonEntityDao nonEntityDao) {
+ super(new EntitySqlDaoTransactionalJdbiWrapper(dbi, clock, cacheControllerDispatcher, nonEntityDao), AccountSqlDao.class);
this.eventBus = eventBus;
this.internalCallContextFactory = internalCallContextFactory;
}
diff --git a/account/src/test/java/com/ning/billing/account/AccountTestBase.java b/account/src/test/java/com/ning/billing/account/AccountTestBase.java
index 6d9acdb..4d85d51 100644
--- a/account/src/test/java/com/ning/billing/account/AccountTestBase.java
+++ b/account/src/test/java/com/ning/billing/account/AccountTestBase.java
@@ -39,12 +39,15 @@ import com.ning.billing.util.audit.dao.AuditDao;
import com.ning.billing.util.audit.dao.DefaultAuditDao;
import com.ning.billing.util.bus.DefaultBusService;
import com.ning.billing.util.bus.InMemoryInternalBus;
+import com.ning.billing.util.cache.CacheControllerDispatcher;
import com.ning.billing.util.callcontext.DefaultCallContextFactory;
import com.ning.billing.util.callcontext.InternalCallContextFactory;
import com.ning.billing.util.clock.Clock;
import com.ning.billing.util.clock.ClockMock;
import com.ning.billing.util.customfield.dao.CustomFieldDao;
import com.ning.billing.util.customfield.dao.DefaultCustomFieldDao;
+import com.ning.billing.util.dao.DefaultNonEntityDao;
+import com.ning.billing.util.dao.NonEntityDao;
import com.ning.billing.util.svcsapi.bus.BusService;
import com.ning.billing.util.svcsapi.bus.InternalBus;
import com.ning.billing.util.tag.api.user.TagEventBuilder;
@@ -66,6 +69,8 @@ public abstract class AccountTestBase extends AccountTestSuiteWithEmbeddedDB {
protected CustomFieldDao customFieldDao;
protected TagDefinitionDao tagDefinitionDao;
protected TagDao tagDao;
+ protected CacheControllerDispatcher controllerDispatcher;
+ protected NonEntityDao nonEntityDao;
protected AccountUserApi accountUserApi;
@@ -74,12 +79,15 @@ public abstract class AccountTestBase extends AccountTestSuiteWithEmbeddedDB {
try {
final IDBI dbi = getDBI();
- final InternalCallContextFactory internalCallContextFactory = new InternalCallContextFactory(dbi, clock);
- accountDao = new DefaultAccountDao(dbi, bus, internalCallContextFactory);
+ controllerDispatcher = new CacheControllerDispatcher();
+ nonEntityDao = new DefaultNonEntityDao(dbi);
+ final InternalCallContextFactory internalCallContextFactory = new InternalCallContextFactory(clock, nonEntityDao, controllerDispatcher);
+ accountDao = new DefaultAccountDao(dbi, bus, clock, controllerDispatcher, internalCallContextFactory, nonEntityDao);
auditDao = new DefaultAuditDao(dbi);
- customFieldDao = new DefaultCustomFieldDao(dbi);
- tagDefinitionDao = new DefaultTagDefinitionDao(dbi, tagEventBuilder, bus);
- tagDao = new DefaultTagDao(dbi, tagEventBuilder, bus);
+ customFieldDao = new DefaultCustomFieldDao(dbi, clock, controllerDispatcher, nonEntityDao);
+ tagDefinitionDao = new DefaultTagDefinitionDao(dbi, tagEventBuilder, bus, clock, controllerDispatcher, nonEntityDao);
+
+ tagDao = new DefaultTagDao(dbi, tagEventBuilder, bus, clock, controllerDispatcher, nonEntityDao);
// Health check test to make sure MySQL is setup properly
accountDao.test(internalCallContext);
@@ -152,6 +160,7 @@ public abstract class AccountTestBase extends AccountTestSuiteWithEmbeddedDB {
}
private AccountData createAccountData(final int billCycleDayUTC, final int billCycleDayLocal, final String phone) {
+
final String externalKey = UUID.randomUUID().toString();
final String email = UUID.randomUUID().toString().substring(0, 4) + '@' + UUID.randomUUID().toString().substring(0, 4);
final String name = UUID.randomUUID().toString();
diff --git a/analytics/src/test/java/com/ning/billing/analytics/AnalyticsTestModule.java b/analytics/src/test/java/com/ning/billing/analytics/AnalyticsTestModule.java
index bd4e9c6..3f4841a 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/AnalyticsTestModule.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/AnalyticsTestModule.java
@@ -32,9 +32,11 @@ import com.ning.billing.util.email.EmailModule;
import com.ning.billing.util.email.templates.TemplateModule;
import com.ning.billing.util.globallocker.TestGlobalLockerModule;
import com.ning.billing.util.glue.BusModule;
+import com.ning.billing.util.glue.CacheModule;
import com.ning.billing.util.glue.CallContextModule;
import com.ning.billing.util.glue.ClockModule;
import com.ning.billing.util.glue.CustomFieldModule;
+import com.ning.billing.util.glue.NonEntityDaoModule;
import com.ning.billing.util.glue.NotificationQueueModule;
import com.ning.billing.util.glue.TagStoreModule;
import com.ning.billing.util.tag.dao.TagDefinitionSqlDao;
@@ -60,6 +62,8 @@ public class AnalyticsTestModule extends AnalyticsModule {
install(new TagStoreModule());
install(new NotificationQueueModule());
install(new DefaultJunctionModule());
+ install(new CacheModule());
+ install(new NonEntityDaoModule());
// Install the Dao layer
final IDBI dbi = KillbillTestSuiteWithEmbeddedDB.getDBI();
diff --git a/analytics/src/test/java/com/ning/billing/analytics/api/user/TestDefaultAnalyticsUserApi.java b/analytics/src/test/java/com/ning/billing/analytics/api/user/TestDefaultAnalyticsUserApi.java
index 783ef2c..03eecba 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/api/user/TestDefaultAnalyticsUserApi.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/api/user/TestDefaultAnalyticsUserApi.java
@@ -59,10 +59,13 @@ import com.ning.billing.catalog.api.Product;
import com.ning.billing.catalog.api.ProductCategory;
import com.ning.billing.entitlement.api.user.Subscription;
import com.ning.billing.mock.MockPlan;
+import com.ning.billing.util.cache.CacheControllerDispatcher;
import com.ning.billing.util.callcontext.InternalCallContextFactory;
import com.ning.billing.util.callcontext.TenantContext;
import com.ning.billing.util.clock.Clock;
import com.ning.billing.util.clock.ClockMock;
+import com.ning.billing.util.dao.DefaultNonEntityDao;
+import com.ning.billing.util.dao.NonEntityDao;
import com.ning.billing.util.svcapi.entitlement.EntitlementInternalApi;
import com.ning.billing.util.svcapi.payment.PaymentInternalApi;
import com.ning.billing.util.svcapi.tag.TagInternalApi;
@@ -84,6 +87,7 @@ public class TestDefaultAnalyticsUserApi extends AnalyticsTestSuiteWithEmbeddedD
@BeforeMethod(groups = "mysql")
public void setUp() throws Exception {
final IDBI dbi = helper.getDBI();
+ final NonEntityDao nonEntityDao = new DefaultNonEntityDao(dbi);
accountSqlDao = dbi.onDemand(BusinessAccountSqlDao.class);
subscriptionTransitionSqlDao = dbi.onDemand(BusinessSubscriptionTransitionSqlDao.class);
invoiceSqlDao = dbi.onDemand(BusinessInvoiceSqlDao.class);
@@ -104,7 +108,7 @@ public class TestDefaultAnalyticsUserApi extends AnalyticsTestSuiteWithEmbeddedD
Mockito.mock(EntitlementInternalApi.class),
Mockito.mock(PaymentInternalApi.class),
Mockito.mock(TagInternalApi.class),
- new InternalCallContextFactory(dbi, clock));
+ new InternalCallContextFactory(clock, nonEntityDao, new CacheControllerDispatcher()));
}
@Test(groups = "mysql")
diff --git a/analytics/src/test/java/com/ning/billing/analytics/TestBusinessTagRecorder.java b/analytics/src/test/java/com/ning/billing/analytics/TestBusinessTagRecorder.java
index cd1877a..f412b9f 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/TestBusinessTagRecorder.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/TestBusinessTagRecorder.java
@@ -51,11 +51,14 @@ import com.ning.billing.entitlement.engine.dao.DefaultEntitlementDao;
import com.ning.billing.entitlement.engine.dao.EntitlementDao;
import com.ning.billing.mock.MockAccountBuilder;
import com.ning.billing.util.bus.InMemoryInternalBus;
+import com.ning.billing.util.cache.CacheControllerDispatcher;
import com.ning.billing.util.callcontext.DefaultCallContextFactory;
import com.ning.billing.util.callcontext.InternalCallContextFactory;
import com.ning.billing.util.clock.Clock;
import com.ning.billing.util.clock.ClockMock;
import com.ning.billing.util.config.CatalogConfig;
+import com.ning.billing.util.dao.DefaultNonEntityDao;
+import com.ning.billing.util.dao.NonEntityDao;
import com.ning.billing.util.notificationq.DefaultNotificationQueueService;
import com.ning.billing.util.notificationq.NotificationQueueConfig;
import com.ning.billing.util.svcapi.account.AccountInternalApi;
@@ -73,7 +76,7 @@ public class TestBusinessTagRecorder extends AnalyticsTestSuiteWithEmbeddedDB {
private EntitlementInternalApi entitlementApi;
private EntitlementUserApi entitlementUserApi;
private BusinessTagDao tagDao;
-
+ private CacheControllerDispatcher controllerDispatcher;
private NotificationQueueConfig config = new NotificationQueueConfig() {
@Override
@@ -96,20 +99,22 @@ public class TestBusinessTagRecorder extends AnalyticsTestSuiteWithEmbeddedDB {
public void setUp() throws Exception {
final Clock clock = new ClockMock();
final IDBI dbi = helper.getDBI();
+ controllerDispatcher = new CacheControllerDispatcher();
+ final NonEntityDao nonEntityDao = new DefaultNonEntityDao(dbi);
accountTagSqlDao = dbi.onDemand(BusinessAccountTagSqlDao.class);
final BusinessInvoiceTagSqlDao invoiceTagSqlDao = dbi.onDemand(BusinessInvoiceTagSqlDao.class);
final BusinessInvoicePaymentTagSqlDao invoicePaymentTagSqlDao = dbi.onDemand(BusinessInvoicePaymentTagSqlDao.class);
subscriptionTransitionTagSqlDao = dbi.onDemand(BusinessSubscriptionTransitionTagSqlDao.class);
eventBus = new InMemoryInternalBus();
- final AccountDao accountDao = new DefaultAccountDao(dbi, eventBus, new InternalCallContextFactory(dbi, new ClockMock()));
+ final AccountDao accountDao = new DefaultAccountDao(dbi, eventBus, clock, controllerDispatcher, new InternalCallContextFactory(new ClockMock(), nonEntityDao, controllerDispatcher), nonEntityDao);
callContextFactory = new DefaultCallContextFactory(clock);
- final InternalCallContextFactory internalCallContextFactory = new InternalCallContextFactory(dbi, clock);
+ final InternalCallContextFactory internalCallContextFactory = new InternalCallContextFactory(clock, nonEntityDao, controllerDispatcher);
accountApi = new DefaultAccountInternalApi(accountDao);
accountUserApi = new DefaultAccountUserApi(callContextFactory, internalCallContextFactory, accountDao);
final CatalogService catalogService = new DefaultCatalogService(Mockito.mock(CatalogConfig.class), Mockito.mock(VersionedCatalogLoader.class));
final AddonUtils addonUtils = new AddonUtils(catalogService);
- final DefaultNotificationQueueService notificationQueueService = new DefaultNotificationQueueService(dbi, clock, config, internalCallContextFactory);
- final EntitlementDao entitlementDao = new DefaultEntitlementDao(dbi, clock, addonUtils, notificationQueueService, eventBus, catalogService);
+ final DefaultNotificationQueueService notificationQueueService = new DefaultNotificationQueueService(dbi, clock, config, internalCallContextFactory, nonEntityDao, controllerDispatcher);
+ final EntitlementDao entitlementDao = new DefaultEntitlementDao(dbi, clock, addonUtils, notificationQueueService, eventBus, catalogService, controllerDispatcher, nonEntityDao);
final PlanAligner planAligner = new PlanAligner(catalogService);
final DefaultSubscriptionApiService apiService = new DefaultSubscriptionApiService(clock, entitlementDao, catalogService, planAligner, addonUtils, internalCallContextFactory);
entitlementApi = new DefaultEntitlementInternalApi(entitlementDao, apiService, clock, catalogService);
diff --git a/beatrix/src/test/java/com/ning/billing/beatrix/integration/BeatrixIntegrationModule.java b/beatrix/src/test/java/com/ning/billing/beatrix/integration/BeatrixIntegrationModule.java
index 982b63c..10b04fe 100644
--- a/beatrix/src/test/java/com/ning/billing/beatrix/integration/BeatrixIntegrationModule.java
+++ b/beatrix/src/test/java/com/ning/billing/beatrix/integration/BeatrixIntegrationModule.java
@@ -62,8 +62,10 @@ import com.ning.billing.util.email.templates.TemplateModule;
import com.ning.billing.util.globallocker.TestGlobalLockerModule;
import com.ning.billing.util.glue.AuditModule;
import com.ning.billing.util.glue.BusModule;
+import com.ning.billing.util.glue.CacheModule;
import com.ning.billing.util.glue.CallContextModule;
import com.ning.billing.util.glue.CustomFieldModule;
+import com.ning.billing.util.glue.NonEntityDaoModule;
import com.ning.billing.util.glue.NotificationQueueModule;
import com.ning.billing.util.glue.TagStoreModule;
import com.ning.billing.util.svcsapi.bus.BusService;
@@ -99,6 +101,7 @@ public class BeatrixIntegrationModule extends AbstractModule {
}
bind(IDBI.class).toInstance(dbi);
+ install(new CacheModule());
install(new EmailModule());
install(new CallContextModule());
install(new TestGlobalLockerModule(helper));
@@ -116,6 +119,7 @@ public class BeatrixIntegrationModule extends AbstractModule {
install(new DefaultJunctionModule());
install(new IntegrationTestOverdueModule());
install(new AuditModule());
+ install(new NonEntityDaoModule());
bind(AccountChecker.class).asEagerSingleton();
bind(EntitlementChecker.class).asEagerSingleton();
diff --git a/beatrix/src/test/java/com/ning/billing/beatrix/util/AuditChecker.java b/beatrix/src/test/java/com/ning/billing/beatrix/util/AuditChecker.java
index ec8e8cf..4d779c9 100644
--- a/beatrix/src/test/java/com/ning/billing/beatrix/util/AuditChecker.java
+++ b/beatrix/src/test/java/com/ning/billing/beatrix/util/AuditChecker.java
@@ -53,6 +53,8 @@ import com.ning.billing.util.audit.ChangeType;
import com.ning.billing.util.callcontext.CallContext;
import com.ning.billing.util.callcontext.InternalCallContextFactory;
import com.ning.billing.util.callcontext.UserType;
+import com.ning.billing.util.dao.NonEntityDao;
+import com.ning.billing.util.dao.TableName;
import com.ning.billing.util.entity.Entity;
import com.ning.billing.util.entity.dao.EntityModelDao;
import com.ning.billing.util.entity.dao.EntitySqlDao;
@@ -66,13 +68,15 @@ public class AuditChecker {
private final AuditUserApi auditUserApi;
private final IDBI dbi;
private final InternalCallContextFactory callContextFactory;
+ private final NonEntityDao nonEntityDao;
@Inject
- public AuditChecker(final AuditUserApi auditUserApi, final IDBI dbi, final InternalCallContextFactory callContextFactory) {
+ public AuditChecker(final AuditUserApi auditUserApi, final IDBI dbi, final InternalCallContextFactory callContextFactory, final NonEntityDao nonEntityDao) {
this.auditUserApi = auditUserApi;
this.dbi = dbi;
this.callContextFactory = callContextFactory;
+ this.nonEntityDao = nonEntityDao;
}
@@ -205,24 +209,28 @@ public class AuditChecker {
// We can't take userToken oustide of the 'if' because for instance NextBillingDate invoice will not have it.
Assert.assertEquals(auditLog.getUserToken(), context.getUserToken().toString());
}
- final M entityModel = extractEntityModelFromEntityWithTargetRecordId(auditLog.getId(), sqlDao, context, useHistory);
+ final M entityModel = extractEntityModelFromEntityWithTargetRecordId(entityId, auditLog.getId(), sqlDao, context, useHistory);
Assert.assertEquals(entityModel.getId(), entityId);
}
- private <T extends EntitySqlDao<M, E>, M extends EntityModelDao<E>, E extends Entity> M extractEntityModelFromEntityWithTargetRecordId(final UUID entityId, final Class<T> sqlDao, final CallContext context, final boolean useHistory) {
+ private <T extends EntitySqlDao<M, E>, M extends EntityModelDao<E>, E extends Entity> M extractEntityModelFromEntityWithTargetRecordId(final UUID entityId, final UUID auditLogId, final Class<T> sqlDao, final CallContext context, final boolean useHistory) {
+
+
+ final M modelDaoThatGivesMeTableName = dbi.onDemand(sqlDao).getById(entityId.toString(), callContextFactory.createInternalCallContext(context));
+
Integer targetRecordId = dbi.withHandle(new HandleCallback<Integer>() {
@Override
public Integer withHandle(final Handle handle) throws Exception {
- List<Map<String, Object>> res = handle.select("select target_record_id from audit_log where id = '" + entityId.toString() + "';");
+ List<Map<String, Object>> res = handle.select("select target_record_id from audit_log where id = '" + auditLogId.toString() + "';");
return (Integer) res.get(0).get("target_record_id");
}
});
if (useHistory) {
- Long entityRecordId = dbi.onDemand(sqlDao).getHistoryTargetRecordId(Long.valueOf(targetRecordId), callContextFactory.createInternalCallContext(context));
+ Long entityRecordId = nonEntityDao.retrieveHistoryTargetRecordId(Long.valueOf(targetRecordId), modelDaoThatGivesMeTableName.getHistoryTableName());
targetRecordId = new Integer(entityRecordId.intValue());
}
return dbi.onDemand(sqlDao).getByRecordId(Long.valueOf(targetRecordId), callContextFactory.createInternalCallContext(context));
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/DefaultEntitlementDao.java b/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/DefaultEntitlementDao.java
index 6aeafe5..a55cb46 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/DefaultEntitlementDao.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/DefaultEntitlementDao.java
@@ -70,9 +70,11 @@ import com.ning.billing.entitlement.events.user.ApiEventChange;
import com.ning.billing.entitlement.events.user.ApiEventMigrateBilling;
import com.ning.billing.entitlement.events.user.ApiEventType;
import com.ning.billing.entitlement.exceptions.EntitlementError;
+import com.ning.billing.util.cache.CacheControllerDispatcher;
import com.ning.billing.util.callcontext.InternalCallContext;
import com.ning.billing.util.callcontext.InternalTenantContext;
import com.ning.billing.util.clock.Clock;
+import com.ning.billing.util.dao.NonEntityDao;
import com.ning.billing.util.entity.EntityPersistenceException;
import com.ning.billing.util.entity.dao.EntitySqlDao;
import com.ning.billing.util.entity.dao.EntitySqlDaoTransactionWrapper;
@@ -105,9 +107,10 @@ public class DefaultEntitlementDao implements EntitlementDao {
@Inject
public DefaultEntitlementDao(final IDBI dbi, final Clock clock, final AddonUtils addonUtils,
- final NotificationQueueService notificationQueueService, final InternalBus eventBus, final CatalogService catalogService) {
+ final NotificationQueueService notificationQueueService, final InternalBus eventBus, final CatalogService catalogService,
+ final CacheControllerDispatcher cacheControllerDispatcher, final NonEntityDao nonEntityDao) {
this.clock = clock;
- this.transactionalSqlDao = new EntitySqlDaoTransactionalJdbiWrapper(dbi);
+ this.transactionalSqlDao = new EntitySqlDaoTransactionalJdbiWrapper(dbi, clock, cacheControllerDispatcher, nonEntityDao);
this.notificationQueueService = notificationQueueService;
this.addonUtils = addonUtils;
this.eventBus = eventBus;
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/model/EntitlementEventModelDao.java b/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/model/EntitlementEventModelDao.java
index 029b78a..f85b5e8 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/model/EntitlementEventModelDao.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/model/EntitlementEventModelDao.java
@@ -287,4 +287,9 @@ public class EntitlementEventModelDao extends EntityBase implements EntityModelD
public TableName getTableName() {
return TableName.SUBSCRIPTION_EVENTS;
}
+
+ @Override
+ public TableName getHistoryTableName() {
+ return null;
+ }
}
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/model/SubscriptionBundleModelDao.java b/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/model/SubscriptionBundleModelDao.java
index 10612c9..2a49d23 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/model/SubscriptionBundleModelDao.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/model/SubscriptionBundleModelDao.java
@@ -116,4 +116,10 @@ public class SubscriptionBundleModelDao extends EntityBase implements EntityMode
public TableName getTableName() {
return TableName.BUNDLES;
}
+
+ @Override
+ public TableName getHistoryTableName() {
+ return null;
+ }
+
}
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/model/SubscriptionModelDao.java b/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/model/SubscriptionModelDao.java
index b208f18..c68f65e 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/model/SubscriptionModelDao.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/model/SubscriptionModelDao.java
@@ -175,4 +175,10 @@ public class SubscriptionModelDao extends EntityBase implements EntityModelDao<S
public TableName getTableName() {
return TableName.SUBSCRIPTIONS;
}
+
+ @Override
+ public TableName getHistoryTableName() {
+ return null;
+ }
+
}
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/transfer/TestDefaultEntitlementTransferApi.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/transfer/TestDefaultEntitlementTransferApi.java
index cf792cc..88efe2b 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/transfer/TestDefaultEntitlementTransferApi.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/transfer/TestDefaultEntitlementTransferApi.java
@@ -46,9 +46,11 @@ import com.ning.billing.entitlement.events.EntitlementEvent;
import com.ning.billing.entitlement.events.EntitlementEvent.EventType;
import com.ning.billing.entitlement.events.user.ApiEventTransfer;
import com.ning.billing.entitlement.events.user.ApiEventType;
+import com.ning.billing.util.cache.CacheControllerDispatcher;
import com.ning.billing.util.callcontext.InternalCallContextFactory;
import com.ning.billing.util.clock.Clock;
import com.ning.billing.util.clock.ClockMock;
+import com.ning.billing.util.dao.NonEntityDao;
import com.google.common.collect.ImmutableList;
@@ -61,11 +63,12 @@ public class TestDefaultEntitlementTransferApi extends EntitlementTestSuite {
@BeforeMethod(groups = "fast")
public void setUp() throws Exception {
+ final NonEntityDao nonEntityDao = Mockito.mock(NonEntityDao.class);
final EntitlementDao dao = Mockito.mock(EntitlementDao.class);
final CatalogService catalogService = new MockCatalogService(new MockCatalog());
final SubscriptionApiService apiService = Mockito.mock(SubscriptionApiService.class);
final EntitlementTimelineApi timelineApi = Mockito.mock(EntitlementTimelineApi.class);
- final InternalCallContextFactory internalCallContextFactory = new InternalCallContextFactory(Mockito.mock(IDBI.class), clock);
+ final InternalCallContextFactory internalCallContextFactory = new InternalCallContextFactory(clock, nonEntityDao, new CacheControllerDispatcher());
transferApi = new DefaultEntitlementTransferApi(clock, dao, timelineApi, catalogService, apiService, internalCallContextFactory);
}
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/engine/dao/MockEntitlementDaoSql.java b/entitlement/src/test/java/com/ning/billing/entitlement/engine/dao/MockEntitlementDaoSql.java
index 228e23f..bc9123f 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/engine/dao/MockEntitlementDaoSql.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/engine/dao/MockEntitlementDaoSql.java
@@ -20,6 +20,8 @@ import org.skife.jdbi.v2.IDBI;
import com.ning.billing.catalog.api.CatalogService;
import com.ning.billing.entitlement.engine.addon.AddonUtils;
+import com.ning.billing.util.cache.CacheControllerDispatcher;
+import com.ning.billing.util.dao.NonEntityDao;
import com.ning.billing.util.svcsapi.bus.InternalBus;
import com.ning.billing.util.clock.Clock;
import com.ning.billing.util.notificationq.NotificationQueueService;
@@ -29,7 +31,7 @@ import com.google.inject.Inject;
public class MockEntitlementDaoSql extends DefaultEntitlementDao {
@Inject
public MockEntitlementDaoSql(final IDBI dbi, final Clock clock, final AddonUtils addonUtils, final NotificationQueueService notificationQueueService,
- final InternalBus eventBus, final CatalogService catalogService) {
- super(dbi, clock, addonUtils, notificationQueueService, eventBus, catalogService);
+ final InternalBus eventBus, final CatalogService catalogService, final CacheControllerDispatcher cacheControllerDispatcher, final NonEntityDao nonEntityDao) {
+ super(dbi, clock, addonUtils, notificationQueueService, eventBus, catalogService, cacheControllerDispatcher, nonEntityDao);
}
}
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/glue/MockEngineModule.java b/entitlement/src/test/java/com/ning/billing/entitlement/glue/MockEngineModule.java
index dd48560..c45dae5 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/glue/MockEngineModule.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/glue/MockEngineModule.java
@@ -21,7 +21,9 @@ import org.mockito.Mockito;
import com.ning.billing.account.api.AccountUserApi;
import com.ning.billing.catalog.glue.CatalogModule;
import com.ning.billing.mock.glue.MockClockModule;
+import com.ning.billing.util.glue.CacheModule;
import com.ning.billing.util.glue.CallContextModule;
+import com.ning.billing.util.glue.NonEntityDaoModule;
public class MockEngineModule extends DefaultEntitlementModule {
@Override
@@ -31,5 +33,6 @@ public class MockEngineModule extends DefaultEntitlementModule {
bind(AccountUserApi.class).toInstance(Mockito.mock(AccountUserApi.class));
install(new MockClockModule());
install(new CallContextModule());
+ install(new CacheModule());
}
}
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/glue/MockEngineModuleMemory.java b/entitlement/src/test/java/com/ning/billing/entitlement/glue/MockEngineModuleMemory.java
index a580f01..63e0a44 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/glue/MockEngineModuleMemory.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/glue/MockEngineModuleMemory.java
@@ -16,16 +16,22 @@
package com.ning.billing.entitlement.glue;
+import java.util.UUID;
+
+import javax.annotation.Nullable;
+
import org.mockito.Mockito;
import org.skife.config.ConfigurationObjectFactory;
import org.skife.jdbi.v2.IDBI;
+import com.ning.billing.ObjectType;
import com.ning.billing.entitlement.api.timeline.RepairEntitlementLifecycleDao;
import com.ning.billing.entitlement.engine.dao.EntitlementDao;
import com.ning.billing.entitlement.engine.dao.MockEntitlementDaoMemory;
import com.ning.billing.entitlement.engine.dao.RepairEntitlementDao;
-import com.ning.billing.util.callcontext.CallContextSqlDao;
-import com.ning.billing.util.callcontext.MockCallContextSqlDao;
+import com.ning.billing.mock.glue.MockNonEntityDaoModule;
+import com.ning.billing.util.cache.CacheController;
+import com.ning.billing.util.dao.NonEntityDao;
import com.ning.billing.util.glue.BusModule;
import com.ning.billing.util.glue.BusModule.BusType;
import com.ning.billing.util.notificationq.MockNotificationQueueService;
@@ -56,7 +62,6 @@ public class MockEngineModuleMemory extends MockEngineModule {
protected void installDBI() {
final IDBI idbi = Mockito.mock(IDBI.class);
- Mockito.when(idbi.onDemand(CallContextSqlDao.class)).thenReturn(new MockCallContextSqlDao());
bind(IDBI.class).toInstance(idbi);
}
@@ -66,5 +71,7 @@ public class MockEngineModuleMemory extends MockEngineModule {
super.configure();
install(new BusModule(BusType.MEMORY));
installNotificationQueue();
+
+ install(new MockNonEntityDaoModule());
}
}
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/glue/MockEngineModuleSql.java b/entitlement/src/test/java/com/ning/billing/entitlement/glue/MockEngineModuleSql.java
index 922fa16..d66a7aa 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/glue/MockEngineModuleSql.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/glue/MockEngineModuleSql.java
@@ -30,6 +30,7 @@ import com.ning.billing.entitlement.engine.dao.RepairEntitlementDao;
import com.ning.billing.util.glue.BusModule;
import com.ning.billing.util.glue.BusModule.BusType;
import com.ning.billing.util.glue.CustomFieldModule;
+import com.ning.billing.util.glue.NonEntityDaoModule;
import com.ning.billing.util.glue.NotificationQueueModule;
import com.google.inject.name.Names;
@@ -57,6 +58,7 @@ public class MockEngineModuleSql extends MockEngineModule {
@Override
protected void configure() {
+ install(new NonEntityDaoModule());
installDBI();
install(new NotificationQueueModule());
install(new CustomFieldModule());
diff --git a/invoice/src/main/java/com/ning/billing/invoice/dao/DefaultInvoiceDao.java b/invoice/src/main/java/com/ning/billing/invoice/dao/DefaultInvoiceDao.java
index 961ced2..30512d3 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/dao/DefaultInvoiceDao.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/dao/DefaultInvoiceDao.java
@@ -41,8 +41,11 @@ import com.ning.billing.invoice.api.InvoicePayment.InvoicePaymentType;
import com.ning.billing.invoice.api.user.DefaultInvoiceAdjustmentEvent;
import com.ning.billing.invoice.model.InvoiceItemList;
import com.ning.billing.invoice.notification.NextBillingDatePoster;
+import com.ning.billing.util.cache.CacheControllerDispatcher;
import com.ning.billing.util.callcontext.InternalCallContext;
import com.ning.billing.util.callcontext.InternalTenantContext;
+import com.ning.billing.util.clock.Clock;
+import com.ning.billing.util.dao.NonEntityDao;
import com.ning.billing.util.entity.EntityPersistenceException;
import com.ning.billing.util.entity.dao.EntityDaoBase;
import com.ning.billing.util.entity.dao.EntitySqlDao;
@@ -70,8 +73,11 @@ public class DefaultInvoiceDao extends EntityDaoBase<InvoiceModelDao, Invoice, I
@Inject
public DefaultInvoiceDao(final IDBI dbi,
final NextBillingDatePoster nextBillingDatePoster,
- final InternalBus eventBus) {
- super(new EntitySqlDaoTransactionalJdbiWrapper(dbi), InvoiceSqlDao.class);
+ final InternalBus eventBus,
+ final Clock clock,
+ final CacheControllerDispatcher cacheControllerDispatcher,
+ final NonEntityDao nonEntityDao) {
+ super(new EntitySqlDaoTransactionalJdbiWrapper(dbi, clock, cacheControllerDispatcher, nonEntityDao), InvoiceSqlDao.class);
this.nextBillingDatePoster = nextBillingDatePoster;
this.eventBus = eventBus;
}
diff --git a/invoice/src/main/java/com/ning/billing/invoice/dao/InvoiceItemModelDao.java b/invoice/src/main/java/com/ning/billing/invoice/dao/InvoiceItemModelDao.java
index 6f289c7..6f99488 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/dao/InvoiceItemModelDao.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/dao/InvoiceItemModelDao.java
@@ -234,4 +234,9 @@ public class InvoiceItemModelDao extends EntityBase implements EntityModelDao<In
public TableName getTableName() {
return TableName.INVOICE_ITEMS;
}
+
+ @Override
+ public TableName getHistoryTableName() {
+ return null;
+ }
}
diff --git a/invoice/src/main/java/com/ning/billing/invoice/dao/InvoiceModelDao.java b/invoice/src/main/java/com/ning/billing/invoice/dao/InvoiceModelDao.java
index f28a0ea..6feb2c9 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/dao/InvoiceModelDao.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/dao/InvoiceModelDao.java
@@ -176,4 +176,10 @@ public class InvoiceModelDao extends EntityBase implements EntityModelDao<Invoic
public TableName getTableName() {
return TableName.INVOICES;
}
+
+ @Override
+ public TableName getHistoryTableName() {
+ return null;
+ }
+
}
diff --git a/invoice/src/main/java/com/ning/billing/invoice/dao/InvoicePaymentModelDao.java b/invoice/src/main/java/com/ning/billing/invoice/dao/InvoicePaymentModelDao.java
index b3462bc..ff8eadc 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/dao/InvoicePaymentModelDao.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/dao/InvoicePaymentModelDao.java
@@ -169,4 +169,9 @@ public class InvoicePaymentModelDao extends EntityBase implements EntityModelDao
public TableName getTableName() {
return TableName.INVOICE_PAYMENTS;
}
+
+ @Override
+ public TableName getHistoryTableName() {
+ return null;
+ }
}
diff --git a/invoice/src/test/java/com/ning/billing/invoice/api/invoice/TestDefaultInvoicePaymentApi.java b/invoice/src/test/java/com/ning/billing/invoice/api/invoice/TestDefaultInvoicePaymentApi.java
index cbb693d..6cfe4cb 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/api/invoice/TestDefaultInvoicePaymentApi.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/api/invoice/TestDefaultInvoicePaymentApi.java
@@ -43,9 +43,12 @@ import com.ning.billing.invoice.dao.InvoiceItemSqlDao;
import com.ning.billing.invoice.dao.InvoiceSqlDao;
import com.ning.billing.invoice.notification.MockNextBillingDatePoster;
import com.ning.billing.invoice.notification.NextBillingDatePoster;
+import com.ning.billing.util.cache.CacheControllerDispatcher;
import com.ning.billing.util.callcontext.InternalCallContextFactory;
import com.ning.billing.util.clock.Clock;
import com.ning.billing.util.clock.ClockMock;
+import com.ning.billing.util.dao.DefaultNonEntityDao;
+import com.ning.billing.util.dao.NonEntityDao;
import com.ning.billing.util.svcapi.invoice.InvoiceInternalApi;
import com.ning.billing.util.svcsapi.bus.InternalBus;
@@ -61,6 +64,7 @@ public class TestDefaultInvoicePaymentApi extends InvoiceTestSuiteWithEmbeddedDB
private static final Currency CURRENCY = Currency.EUR;
private final Clock clock = new ClockMock();
+ private final CacheControllerDispatcher controllerDispatcher = new CacheControllerDispatcher();
private InvoiceSqlDao invoiceSqlDao;
private InvoiceItemSqlDao invoiceItemSqlDao;
@@ -78,9 +82,10 @@ public class TestDefaultInvoicePaymentApi extends InvoiceTestSuiteWithEmbeddedDB
invoiceItemSqlDao = dbi.onDemand(InvoiceItemSqlDao.class);
invoiceItemSqlDao.test(internalCallContext);
+ final NonEntityDao nonEntityDao = new DefaultNonEntityDao(dbi);
final NextBillingDatePoster nextBillingDatePoster = new MockNextBillingDatePoster();
- internalCallContextFactory = new InternalCallContextFactory(dbi, clock);
- final InvoiceDao invoiceDao = new DefaultInvoiceDao(dbi, nextBillingDatePoster, Mockito.mock(InternalBus.class));
+ internalCallContextFactory = new InternalCallContextFactory(clock, nonEntityDao, controllerDispatcher);
+ final InvoiceDao invoiceDao = new DefaultInvoiceDao(dbi, nextBillingDatePoster, Mockito.mock(InternalBus.class), clock, controllerDispatcher, nonEntityDao);
invoicePaymentApi = new DefaultInvoicePaymentApi(invoiceDao, internalCallContextFactory);
invoiceInternalApi = new DefaultInvoiceInternalApi(invoiceDao);
}
diff --git a/invoice/src/test/java/com/ning/billing/invoice/api/migration/MockModuleNoEntitlement.java b/invoice/src/test/java/com/ning/billing/invoice/api/migration/MockModuleNoEntitlement.java
index 3266965..8286665 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/api/migration/MockModuleNoEntitlement.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/api/migration/MockModuleNoEntitlement.java
@@ -26,6 +26,7 @@ import com.ning.billing.invoice.notification.NextBillingDateNotifier;
import com.ning.billing.invoice.notification.NextBillingDatePoster;
import com.ning.billing.invoice.notification.NullInvoiceNotifier;
import com.ning.billing.util.email.templates.TemplateModule;
+import com.ning.billing.util.glue.CacheModule;
import com.ning.billing.util.template.translation.TranslatorConfig;
public class MockModuleNoEntitlement extends MockModule {
diff --git a/invoice/src/test/java/com/ning/billing/invoice/dao/InvoiceDaoTestBase.java b/invoice/src/test/java/com/ning/billing/invoice/dao/InvoiceDaoTestBase.java
index 7559994..6bfe42d 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/dao/InvoiceDaoTestBase.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/dao/InvoiceDaoTestBase.java
@@ -39,10 +39,12 @@ import com.ning.billing.invoice.notification.MockNextBillingDatePoster;
import com.ning.billing.invoice.notification.NextBillingDatePoster;
import com.ning.billing.invoice.tests.InvoicingTestBase;
import com.ning.billing.util.bus.InMemoryInternalBus;
+import com.ning.billing.util.cache.CacheControllerDispatcher;
import com.ning.billing.util.callcontext.InternalCallContext;
import com.ning.billing.util.clock.Clock;
import com.ning.billing.util.clock.ClockMock;
import com.ning.billing.util.config.InvoiceConfig;
+import com.ning.billing.util.dao.DefaultNonEntityDao;
import com.ning.billing.util.entity.EntityPersistenceException;
import com.ning.billing.util.svcsapi.bus.InternalBus;
@@ -63,6 +65,8 @@ public class InvoiceDaoTestBase extends InvoicingTestBase {
protected Clock clock;
protected InvoiceGenerator generator;
protected InternalBus bus;
+ protected CacheControllerDispatcher controllerDispatcher;
+
private final InvoiceConfig invoiceConfig = new InvoiceConfig() {
@Override
@@ -99,7 +103,9 @@ public class InvoiceDaoTestBase extends InvoicingTestBase {
bus.start();
final NextBillingDatePoster nextBillingDatePoster = new MockNextBillingDatePoster();
- invoiceDao = new DefaultInvoiceDao(dbi, nextBillingDatePoster, bus);
+ controllerDispatcher = new CacheControllerDispatcher();
+
+ invoiceDao = new DefaultInvoiceDao(dbi, nextBillingDatePoster, bus, clock, controllerDispatcher, new DefaultNonEntityDao(dbi));
invoiceDao.test(internalCallContext);
invoiceItemSqlDao = dbi.onDemand(InvoiceItemSqlDao.class);
diff --git a/invoice/src/test/java/com/ning/billing/invoice/dao/TestDefaultInvoiceDao.java b/invoice/src/test/java/com/ning/billing/invoice/dao/TestDefaultInvoiceDao.java
index e3bb748..16b0c48 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/dao/TestDefaultInvoiceDao.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/dao/TestDefaultInvoiceDao.java
@@ -30,10 +30,12 @@ import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import com.ning.billing.ErrorCode;
+import com.ning.billing.dao.MockNonEntityDao;
import com.ning.billing.invoice.InvoiceTestSuite;
import com.ning.billing.invoice.api.Invoice;
import com.ning.billing.invoice.api.InvoiceApiException;
import com.ning.billing.invoice.notification.NextBillingDatePoster;
+import com.ning.billing.util.cache.CacheControllerDispatcher;
import com.ning.billing.util.callcontext.InternalTenantContext;
import com.ning.billing.util.entity.dao.EntitySqlDao;
import com.ning.billing.util.svcsapi.bus.InternalBus;
@@ -44,6 +46,8 @@ public class TestDefaultInvoiceDao extends InvoiceTestSuite {
private InvoiceSqlDao invoiceSqlDao;
private DefaultInvoiceDao dao;
+ private final CacheControllerDispatcher controllerDispatcher = new CacheControllerDispatcher();
+
@BeforeMethod(groups = "fast")
public void setUp() throws Exception {
@@ -65,7 +69,7 @@ public class TestDefaultInvoiceDao extends InvoiceTestSuite {
});
final NextBillingDatePoster poster = Mockito.mock(NextBillingDatePoster.class);
- dao = new DefaultInvoiceDao(idbi, poster, Mockito.mock(InternalBus.class));
+ dao = new DefaultInvoiceDao(idbi, poster, Mockito.mock(InternalBus.class), clock, controllerDispatcher, new MockNonEntityDao());
}
@Test(groups = "fast")
diff --git a/invoice/src/test/java/com/ning/billing/invoice/MockModule.java b/invoice/src/test/java/com/ning/billing/invoice/MockModule.java
index 65b6571..d63a881 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/MockModule.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/MockModule.java
@@ -42,7 +42,9 @@ import com.ning.billing.util.email.EmailModule;
import com.ning.billing.util.email.templates.TemplateModule;
import com.ning.billing.util.globallocker.TestGlobalLockerModule;
import com.ning.billing.util.glue.BusModule;
+import com.ning.billing.util.glue.CacheModule;
import com.ning.billing.util.glue.CustomFieldModule;
+import com.ning.billing.util.glue.NonEntityDaoModule;
import com.ning.billing.util.glue.NotificationQueueModule;
import com.ning.billing.util.glue.TagStoreModule;
import com.ning.billing.util.svcapi.account.AccountInternalApi;
@@ -64,6 +66,8 @@ public class MockModule extends AbstractModule {
bind(CallContextFactory.class).to(DefaultCallContextFactory.class).asEagerSingleton();
install(new TagStoreModule());
install(new CustomFieldModule());
+ install(new CacheModule());
+ install(new NonEntityDaoModule());
final DBTestingHelper helper = KillbillTestSuiteWithEmbeddedDB.getDBTestingHelper();
if (helper.isUsingLocalInstance()) {
@@ -75,9 +79,10 @@ public class MockModule extends AbstractModule {
bind(IDBI.class).toInstance(dbi);
}
- final InternalCallContextFactory internalCallContextFactory = new InternalCallContextFactory(helper.getDBI(), clock);
+ /*
+ final InternalCallContextFactory internalCallContextFactory = new InternalCallContextFactory(helper.getDBI(), clock, nonEntityDao);
bind(InternalCallContextFactory.class).toInstance(internalCallContextFactory);
-
+*/
bind(InvoiceFormatterFactory.class).to(DefaultInvoiceFormatterFactory.class).asEagerSingleton();
bind(AccountInternalApi.class).toInstance(Mockito.mock(AccountInternalApi.class));
diff --git a/invoice/src/test/java/com/ning/billing/invoice/notification/TestNextBillingDateNotifier.java b/invoice/src/test/java/com/ning/billing/invoice/notification/TestNextBillingDateNotifier.java
index 15d08b6..3d5cc76 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/notification/TestNextBillingDateNotifier.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/notification/TestNextBillingDateNotifier.java
@@ -45,11 +45,13 @@ import com.ning.billing.invoice.glue.InvoiceModuleWithMocks;
import com.ning.billing.invoice.template.formatters.DefaultInvoiceFormatterFactory;
import com.ning.billing.lifecycle.KillbillService;
import com.ning.billing.mock.glue.MockJunctionModule;
+import com.ning.billing.util.cache.CacheControllerDispatcher;
import com.ning.billing.util.callcontext.InternalCallContextFactory;
import com.ning.billing.util.callcontext.InternalTenantContext;
import com.ning.billing.util.clock.Clock;
import com.ning.billing.util.clock.ClockMock;
import com.ning.billing.util.config.InvoiceConfig;
+import com.ning.billing.util.dao.NonEntityDao;
import com.ning.billing.util.email.templates.TemplateModule;
import com.ning.billing.util.entity.dao.EntitySqlDao;
import com.ning.billing.util.entity.dao.EntitySqlDaoTransactionWrapper;
@@ -57,6 +59,8 @@ import com.ning.billing.util.entity.dao.EntitySqlDaoTransactionalJdbiWrapper;
import com.ning.billing.util.entity.dao.EntitySqlDaoWrapperFactory;
import com.ning.billing.util.glue.BusModule;
import com.ning.billing.util.glue.BusModule.BusType;
+import com.ning.billing.util.glue.CacheModule;
+import com.ning.billing.util.glue.NonEntityDaoModule;
import com.ning.billing.util.glue.NotificationQueueModule;
import com.ning.billing.util.glue.TagStoreModule;
import com.ning.billing.util.notificationq.NotificationQueueService;
@@ -81,6 +85,8 @@ public class TestNextBillingDateNotifier extends InvoiceTestSuiteWithEmbeddedDB
private NotificationQueueService notificationQueueService;
private InternalCallContextFactory internalCallContextFactory;
private EntitySqlDaoTransactionalJdbiWrapper entitySqlDaoTransactionalJdbiWrapper;
+ private CacheControllerDispatcher controllerDispatcher;
+ private NonEntityDao nonEntityDao;
private static final class InvoiceListenerMock extends InvoiceListener {
@@ -125,6 +131,8 @@ public class TestNextBillingDateNotifier extends InvoiceTestSuiteWithEmbeddedDB
install(new NotificationQueueModule());
install(new TemplateModule());
install(new TagStoreModule());
+ install(new CacheModule());
+ install(new NonEntityDaoModule());
final DBTestingHelper helper = KillbillTestSuiteWithEmbeddedDB.getDBTestingHelper();
if (helper.isUsingLocalInstance()) {
@@ -136,9 +144,10 @@ public class TestNextBillingDateNotifier extends InvoiceTestSuiteWithEmbeddedDB
bind(IDBI.class).toInstance(dbi);
}
- final InternalCallContextFactory internalCallContextFactory = new InternalCallContextFactory(helper.getDBI(), clock);
+ /*
+ final InternalCallContextFactory internalCallContextFactory = new InternalCallContextFactory(helper.getDBI(), clock, nonEntityDao);
bind(InternalCallContextFactory.class).toInstance(internalCallContextFactory);
-
+*/
bind(InvoiceFormatterFactory.class).to(DefaultInvoiceFormatterFactory.class).asEagerSingleton();
bind(AccountInternalApi.class).toInstance(Mockito.mock(AccountInternalApi.class));
@@ -149,7 +158,10 @@ public class TestNextBillingDateNotifier extends InvoiceTestSuiteWithEmbeddedDB
clock = g.getInstance(Clock.class);
final IDBI dbi = g.getInstance(IDBI.class);
- entitySqlDaoTransactionalJdbiWrapper = new EntitySqlDaoTransactionalJdbiWrapper(dbi);
+ nonEntityDao = g.getInstance(NonEntityDao.class);
+ controllerDispatcher = g.getInstance(CacheControllerDispatcher.class);
+
+ entitySqlDaoTransactionalJdbiWrapper = new EntitySqlDaoTransactionalJdbiWrapper(dbi, clock, controllerDispatcher, nonEntityDao);
eventBus = g.getInstance(InternalBus.class);
notificationQueueService = g.getInstance(NotificationQueueService.class);
diff --git a/invoice/src/test/java/com/ning/billing/invoice/tests/TestChargeBacks.java b/invoice/src/test/java/com/ning/billing/invoice/tests/TestChargeBacks.java
index 8e701dd..bd980a0 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/tests/TestChargeBacks.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/tests/TestChargeBacks.java
@@ -44,9 +44,12 @@ import com.ning.billing.invoice.dao.InvoiceSqlDao;
import com.ning.billing.invoice.glue.InvoiceModuleWithEmbeddedDb;
import com.ning.billing.invoice.notification.MockNextBillingDatePoster;
import com.ning.billing.invoice.notification.NextBillingDatePoster;
+import com.ning.billing.util.cache.CacheControllerDispatcher;
import com.ning.billing.util.callcontext.InternalCallContextFactory;
import com.ning.billing.util.clock.Clock;
import com.ning.billing.util.clock.ClockMock;
+import com.ning.billing.util.dao.DefaultNonEntityDao;
+import com.ning.billing.util.dao.NonEntityDao;
import com.ning.billing.util.svcapi.invoice.InvoiceInternalApi;
import com.ning.billing.util.svcsapi.bus.InternalBus;
@@ -69,6 +72,8 @@ public class TestChargeBacks extends InvoiceTestSuiteWithEmbeddedDB {
private InternalCallContextFactory internalCallContextFactory;
private final Clock clock = new ClockMock();
+ private final CacheControllerDispatcher controllerDispatcher = new CacheControllerDispatcher();
+
private static final Currency CURRENCY = Currency.EUR;
@BeforeSuite(groups = "slow")
@@ -80,11 +85,12 @@ public class TestChargeBacks extends InvoiceTestSuiteWithEmbeddedDB {
invoiceSqlDao = dbi.onDemand(InvoiceSqlDao.class);
invoiceSqlDao.test(internalCallContext);
+ final NonEntityDao nonEntityDao = new DefaultNonEntityDao(dbi);
invoiceItemSqlDao = dbi.onDemand(InvoiceItemSqlDao.class);
invoiceItemSqlDao.test(internalCallContext);
final NextBillingDatePoster nextBillingDatePoster = new MockNextBillingDatePoster();
- internalCallContextFactory = new InternalCallContextFactory(dbi, clock);
- final InvoiceDao invoiceDao = new DefaultInvoiceDao(dbi, nextBillingDatePoster, Mockito.mock(InternalBus.class));
+ internalCallContextFactory = new InternalCallContextFactory(clock, nonEntityDao, controllerDispatcher);
+ final InvoiceDao invoiceDao = new DefaultInvoiceDao(dbi, nextBillingDatePoster, Mockito.mock(InternalBus.class), clock, controllerDispatcher, nonEntityDao);
invoicePaymentApi = new DefaultInvoicePaymentApi(invoiceDao, internalCallContextFactory);
invoiceApi = new DefaultInvoiceInternalApi(invoiceDao);
}
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/InvoiceResource.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/InvoiceResource.java
index 952bf60..42ac6a1 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/InvoiceResource.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/InvoiceResource.java
@@ -178,7 +178,7 @@ public class InvoiceResource extends JaxRsResourceBase {
final Account account = accountApi.getAccountById(UUID.fromString(accountId), callContext);
- final DateTime inputDateTime = DATE_TIME_FORMATTER.parseDateTime(targetDateTime);
+ final DateTime inputDateTime = targetDateTime != null ? DATE_TIME_FORMATTER.parseDateTime(targetDateTime) : clock.getUTCNow();
final LocalDate inputDate = inputDateTime.toDateTime(account.getTimeZone()).toLocalDate();
final Invoice generatedInvoice = invoiceApi.triggerInvoiceGeneration(UUID.fromString(accountId), inputDate, dryRun,
diff --git a/junction/src/main/java/com/ning/billing/junction/dao/BlockingStateModelDao.java b/junction/src/main/java/com/ning/billing/junction/dao/BlockingStateModelDao.java
index 5dbdd25..a1c7bfc 100644
--- a/junction/src/main/java/com/ning/billing/junction/dao/BlockingStateModelDao.java
+++ b/junction/src/main/java/com/ning/billing/junction/dao/BlockingStateModelDao.java
@@ -98,6 +98,11 @@ public class BlockingStateModelDao extends EntityBase implements EntityModelDao<
}
@Override
+ public TableName getHistoryTableName() {
+ return null;
+ }
+
+ @Override
public String toString() {
final StringBuilder sb = new StringBuilder();
sb.append("BlockingStateModelDao");
diff --git a/junction/src/main/java/com/ning/billing/junction/dao/DefaultBlockingStateDao.java b/junction/src/main/java/com/ning/billing/junction/dao/DefaultBlockingStateDao.java
index 1ea8e5a..8ed806f 100644
--- a/junction/src/main/java/com/ning/billing/junction/dao/DefaultBlockingStateDao.java
+++ b/junction/src/main/java/com/ning/billing/junction/dao/DefaultBlockingStateDao.java
@@ -27,9 +27,11 @@ import org.skife.jdbi.v2.IDBI;
import com.ning.billing.junction.api.Blockable;
import com.ning.billing.junction.api.BlockingState;
+import com.ning.billing.util.cache.CacheControllerDispatcher;
import com.ning.billing.util.callcontext.InternalCallContext;
import com.ning.billing.util.callcontext.InternalTenantContext;
import com.ning.billing.util.clock.Clock;
+import com.ning.billing.util.dao.NonEntityDao;
import com.ning.billing.util.entity.dao.EntitySqlDao;
import com.ning.billing.util.entity.dao.EntitySqlDaoTransactionWrapper;
import com.ning.billing.util.entity.dao.EntitySqlDaoTransactionalJdbiWrapper;
@@ -43,8 +45,8 @@ public class DefaultBlockingStateDao implements BlockingStateDao {
private final EntitySqlDaoTransactionalJdbiWrapper transactionalSqlDao;
@Inject
- public DefaultBlockingStateDao(final IDBI dbi) {
- this.transactionalSqlDao = new EntitySqlDaoTransactionalJdbiWrapper(dbi);
+ public DefaultBlockingStateDao(final IDBI dbi, final Clock clock, final CacheControllerDispatcher cacheControllerDispatcher, final NonEntityDao nonEntityDao) {
+ this.transactionalSqlDao = new EntitySqlDaoTransactionalJdbiWrapper(dbi, clock, cacheControllerDispatcher, nonEntityDao);
}
@Override
diff --git a/junction/src/test/java/com/ning/billing/junction/api/blocking/TestDefaultBlockingApi.java b/junction/src/test/java/com/ning/billing/junction/api/blocking/TestDefaultBlockingApi.java
index eeb92dc..8758d44 100644
--- a/junction/src/test/java/com/ning/billing/junction/api/blocking/TestDefaultBlockingApi.java
+++ b/junction/src/test/java/com/ning/billing/junction/api/blocking/TestDefaultBlockingApi.java
@@ -32,18 +32,23 @@ import com.ning.billing.junction.api.svcs.DefaultInternalBlockingApi;
import com.ning.billing.junction.api.BlockingState;
import com.ning.billing.junction.dao.BlockingStateDao;
import com.ning.billing.junction.dao.DefaultBlockingStateDao;
+import com.ning.billing.util.cache.CacheControllerDispatcher;
import com.ning.billing.util.clock.ClockMock;
+import com.ning.billing.util.dao.DefaultNonEntityDao;
import com.ning.billing.util.svcapi.junction.DefaultBlockingState;
public class TestDefaultBlockingApi extends JunctionTestSuiteWithEmbeddedDB {
private final ClockMock clock = new ClockMock();
+ private final CacheControllerDispatcher controllerDispatcher = new CacheControllerDispatcher();
+
private DefaultInternalBlockingApi blockingApi;
+
@BeforeMethod(groups = "slow")
public void setUp() throws Exception {
- final BlockingStateDao blockingStateDao = new DefaultBlockingStateDao(getDBI());
+ final BlockingStateDao blockingStateDao = new DefaultBlockingStateDao(getDBI(), clock, controllerDispatcher, new DefaultNonEntityDao(getDBI()));
blockingApi = new DefaultInternalBlockingApi(blockingStateDao, clock);
}
diff --git a/junction/src/test/java/com/ning/billing/junction/MockModule.java b/junction/src/test/java/com/ning/billing/junction/MockModule.java
index 7865bcd..7d2ae94 100644
--- a/junction/src/test/java/com/ning/billing/junction/MockModule.java
+++ b/junction/src/test/java/com/ning/billing/junction/MockModule.java
@@ -20,7 +20,9 @@ import com.ning.billing.catalog.glue.CatalogModule;
import com.ning.billing.junction.glue.DefaultJunctionModule;
import com.ning.billing.mock.glue.MockClockModule;
import com.ning.billing.mock.glue.MockDbHelperModule;
+import com.ning.billing.util.glue.CacheModule;
import com.ning.billing.util.glue.CallContextModule;
+import com.ning.billing.util.glue.NonEntityDaoModule;
public class MockModule extends DefaultJunctionModule {
@Override
@@ -31,6 +33,8 @@ public class MockModule extends DefaultJunctionModule {
install(new MockDbHelperModule());
install(new CallContextModule());
install(new CatalogModule());
+ install(new CacheModule());
+ install(new NonEntityDaoModule());
}
@Override
diff --git a/meter/src/test/java/com/ning/billing/meter/timeline/aggregator/TestTimelineAggregator.java b/meter/src/test/java/com/ning/billing/meter/timeline/aggregator/TestTimelineAggregator.java
index 716a4e3..acb9341 100644
--- a/meter/src/test/java/com/ning/billing/meter/timeline/aggregator/TestTimelineAggregator.java
+++ b/meter/src/test/java/com/ning/billing/meter/timeline/aggregator/TestTimelineAggregator.java
@@ -24,6 +24,7 @@ import java.util.concurrent.atomic.AtomicLong;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
+import org.mockito.Mockito;
import org.skife.config.ConfigurationObjectFactory;
import org.testng.Assert;
import org.testng.annotations.BeforeMethod;
@@ -42,9 +43,11 @@ import com.ning.billing.meter.timeline.samples.ScalarSample;
import com.ning.billing.meter.timeline.sources.SourceSamplesForTimestamp;
import com.ning.billing.meter.timeline.times.DefaultTimelineCoder;
import com.ning.billing.meter.timeline.times.TimelineCoder;
+import com.ning.billing.util.cache.CacheControllerDispatcher;
import com.ning.billing.util.callcontext.InternalCallContextFactory;
import com.ning.billing.util.clock.ClockMock;
import com.ning.billing.util.config.MeterConfig;
+import com.ning.billing.util.dao.NonEntityDao;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
@@ -61,7 +64,8 @@ public class TestTimelineAggregator extends MeterTestSuiteWithEmbeddedDB {
private static final TimelineCoder timelineCoder = new DefaultTimelineCoder();
private static final SampleCoder sampleCoder = new DefaultSampleCoder();
- private final InternalCallContextFactory internalCallContextFactory = new InternalCallContextFactory(getDBI(), new ClockMock());
+ private final NonEntityDao nonEntityDao = Mockito.mock(NonEntityDao.class);
+ private final InternalCallContextFactory internalCallContextFactory = new InternalCallContextFactory(new ClockMock(), nonEntityDao, new CacheControllerDispatcher());
private TimelineDao timelineDao;
private TimelineAggregator aggregator;
diff --git a/meter/src/test/java/com/ning/billing/meter/timeline/persistent/TestFileBackedBuffer.java b/meter/src/test/java/com/ning/billing/meter/timeline/persistent/TestFileBackedBuffer.java
index b41aec0..d6a789c 100644
--- a/meter/src/test/java/com/ning/billing/meter/timeline/persistent/TestFileBackedBuffer.java
+++ b/meter/src/test/java/com/ning/billing/meter/timeline/persistent/TestFileBackedBuffer.java
@@ -44,9 +44,11 @@ import com.ning.billing.meter.timeline.codec.SampleCoder;
import com.ning.billing.meter.timeline.sources.SourceSamplesForTimestamp;
import com.ning.billing.meter.timeline.times.DefaultTimelineCoder;
import com.ning.billing.meter.timeline.times.TimelineCoder;
+import com.ning.billing.util.cache.CacheControllerDispatcher;
import com.ning.billing.util.callcontext.InternalCallContextFactory;
import com.ning.billing.util.clock.ClockMock;
import com.ning.billing.util.config.MeterConfig;
+import com.ning.billing.util.dao.NonEntityDao;
import com.google.common.collect.ImmutableMap;
@@ -64,7 +66,8 @@ public class TestFileBackedBuffer extends MeterTestSuite {
private static final TimelineCoder timelineCoder = new DefaultTimelineCoder();
private static final SampleCoder sampleCoder = new DefaultSampleCoder();
- private final InternalCallContextFactory internalCallContextFactory = new InternalCallContextFactory(Mockito.mock(DBI.class), new ClockMock());
+ private final NonEntityDao nonEntityDao = Mockito.mock(NonEntityDao.class);
+ private final InternalCallContextFactory internalCallContextFactory = new InternalCallContextFactory(new ClockMock(), nonEntityDao, new CacheControllerDispatcher());
private final TimelineDao dao = new MockTimelineDao();
private TimelineEventHandler timelineEventHandler;
diff --git a/meter/src/test/java/com/ning/billing/meter/timeline/persistent/TestSamplesReplayer.java b/meter/src/test/java/com/ning/billing/meter/timeline/persistent/TestSamplesReplayer.java
index 4da4131..75016d1 100644
--- a/meter/src/test/java/com/ning/billing/meter/timeline/persistent/TestSamplesReplayer.java
+++ b/meter/src/test/java/com/ning/billing/meter/timeline/persistent/TestSamplesReplayer.java
@@ -40,8 +40,11 @@ import com.ning.billing.meter.timeline.samples.ScalarSample;
import com.ning.billing.meter.timeline.sources.SourceSamplesForTimestamp;
import com.ning.billing.meter.timeline.times.DefaultTimelineCoder;
import com.ning.billing.meter.timeline.times.TimelineCoder;
+import com.ning.billing.util.cache.CacheController;
+import com.ning.billing.util.cache.CacheControllerDispatcher;
import com.ning.billing.util.callcontext.InternalCallContextFactory;
import com.ning.billing.util.clock.ClockMock;
+import com.ning.billing.util.dao.NonEntityDao;
import com.google.common.collect.ImmutableMap;
@@ -58,7 +61,8 @@ public class TestSamplesReplayer extends MeterTestSuite {
private static final TimelineCoder timelineCoder = new DefaultTimelineCoder();
private static final SampleCoder sampleCoder = new DefaultSampleCoder();
- private final InternalCallContextFactory internalCallContextFactory = new InternalCallContextFactory(Mockito.mock(DBI.class), new ClockMock());
+ private final NonEntityDao nonEntityDao = Mockito.mock(NonEntityDao.class);
+ private final InternalCallContextFactory internalCallContextFactory = new InternalCallContextFactory(new ClockMock(), nonEntityDao, new CacheControllerDispatcher());
@BeforeMethod(groups = "fast")
public void setUp() throws Exception {
diff --git a/meter/src/test/java/com/ning/billing/meter/timeline/TestInMemoryEventHandler.java b/meter/src/test/java/com/ning/billing/meter/timeline/TestInMemoryEventHandler.java
index 2ee5851..ddd884d 100644
--- a/meter/src/test/java/com/ning/billing/meter/timeline/TestInMemoryEventHandler.java
+++ b/meter/src/test/java/com/ning/billing/meter/timeline/TestInMemoryEventHandler.java
@@ -36,9 +36,11 @@ import com.ning.billing.meter.timeline.persistent.FileBackedBuffer;
import com.ning.billing.meter.timeline.persistent.TimelineDao;
import com.ning.billing.meter.timeline.times.DefaultTimelineCoder;
import com.ning.billing.meter.timeline.times.TimelineCoder;
+import com.ning.billing.util.cache.CacheControllerDispatcher;
import com.ning.billing.util.callcontext.InternalCallContextFactory;
import com.ning.billing.util.clock.ClockMock;
import com.ning.billing.util.config.MeterConfig;
+import com.ning.billing.util.dao.NonEntityDao;
import com.google.common.collect.ImmutableMap;
@@ -54,7 +56,9 @@ public class TestInMemoryEventHandler extends MeterTestSuite {
private static final TimelineCoder timelineCoder = new DefaultTimelineCoder();
private static final SampleCoder sampleCoder = new DefaultSampleCoder();
- private final InternalCallContextFactory internalCallContextFactory = new InternalCallContextFactory(Mockito.mock(DBI.class), new ClockMock());
+ private final NonEntityDao nonEntityDao = Mockito.mock(NonEntityDao.class);
+ private final InternalCallContextFactory internalCallContextFactory = new InternalCallContextFactory(new ClockMock(), nonEntityDao, new CacheControllerDispatcher());
+
private final TimelineDao dao = new MockTimelineDao();
private TimelineEventHandler timelineEventHandler;
diff --git a/meter/src/test/java/com/ning/billing/meter/timeline/TestTimelineEventHandler.java b/meter/src/test/java/com/ning/billing/meter/timeline/TestTimelineEventHandler.java
index 89d5512..4ac3c31 100644
--- a/meter/src/test/java/com/ning/billing/meter/timeline/TestTimelineEventHandler.java
+++ b/meter/src/test/java/com/ning/billing/meter/timeline/TestTimelineEventHandler.java
@@ -36,9 +36,11 @@ import com.ning.billing.meter.timeline.samples.ScalarSample;
import com.ning.billing.meter.timeline.sources.SourceSamplesForTimestamp;
import com.ning.billing.meter.timeline.times.DefaultTimelineCoder;
import com.ning.billing.meter.timeline.times.TimelineCoder;
+import com.ning.billing.util.cache.CacheControllerDispatcher;
import com.ning.billing.util.callcontext.InternalCallContextFactory;
import com.ning.billing.util.clock.ClockMock;
import com.ning.billing.util.config.MeterConfig;
+import com.ning.billing.util.dao.NonEntityDao;
import com.google.common.collect.ImmutableMap;
@@ -49,7 +51,8 @@ public class TestTimelineEventHandler extends MeterTestSuite {
private static final TimelineCoder timelineCoder = new DefaultTimelineCoder();
private static final SampleCoder sampleCoder = new DefaultSampleCoder();
- private final InternalCallContextFactory internalCallContextFactory = new InternalCallContextFactory(Mockito.mock(DBI.class), new ClockMock());
+ private final NonEntityDao nonEntityDao = Mockito.mock(NonEntityDao.class);
+ private final InternalCallContextFactory internalCallContextFactory = new InternalCallContextFactory(new ClockMock(), nonEntityDao, new CacheControllerDispatcher());
private final TimelineDao dao = new MockTimelineDao();
diff --git a/meter/src/test/java/com/ning/billing/meter/timeline/TestTimelineSourceEventAccumulator.java b/meter/src/test/java/com/ning/billing/meter/timeline/TestTimelineSourceEventAccumulator.java
index 55dd0b8..d676171 100644
--- a/meter/src/test/java/com/ning/billing/meter/timeline/TestTimelineSourceEventAccumulator.java
+++ b/meter/src/test/java/com/ning/billing/meter/timeline/TestTimelineSourceEventAccumulator.java
@@ -35,8 +35,10 @@ import com.ning.billing.meter.timeline.samples.ScalarSample;
import com.ning.billing.meter.timeline.sources.SourceSamplesForTimestamp;
import com.ning.billing.meter.timeline.times.DefaultTimelineCoder;
import com.ning.billing.meter.timeline.times.TimelineCoder;
+import com.ning.billing.util.cache.CacheControllerDispatcher;
import com.ning.billing.util.callcontext.InternalCallContextFactory;
import com.ning.billing.util.clock.ClockMock;
+import com.ning.billing.util.dao.NonEntityDao;
public class TestTimelineSourceEventAccumulator extends MeterTestSuite {
@@ -47,7 +49,8 @@ public class TestTimelineSourceEventAccumulator extends MeterTestSuite {
private static final TimelineCoder timelineCoder = new DefaultTimelineCoder();
private static final SampleCoder sampleCoder = new DefaultSampleCoder();
- private final InternalCallContextFactory internalCallContextFactory = new InternalCallContextFactory(Mockito.mock(DBI.class), new ClockMock());
+ private final NonEntityDao nonEntityDao = Mockito.mock(NonEntityDao.class);
+ private final InternalCallContextFactory internalCallContextFactory = new InternalCallContextFactory(new ClockMock(), nonEntityDao, new CacheControllerDispatcher());
@Test(groups = "fast")
public void testSimpleAggregate() throws IOException {
diff --git a/overdue/src/test/java/com/ning/billing/overdue/notification/TestOverdueCheckNotifier.java b/overdue/src/test/java/com/ning/billing/overdue/notification/TestOverdueCheckNotifier.java
index 4e283e1..7b21af7 100644
--- a/overdue/src/test/java/com/ning/billing/overdue/notification/TestOverdueCheckNotifier.java
+++ b/overdue/src/test/java/com/ning/billing/overdue/notification/TestOverdueCheckNotifier.java
@@ -49,6 +49,7 @@ import com.ning.billing.overdue.OverdueProperties;
import com.ning.billing.overdue.OverdueTestSuiteWithEmbeddedDB;
import com.ning.billing.overdue.glue.DefaultOverdueModule;
import com.ning.billing.overdue.listener.OverdueListener;
+import com.ning.billing.util.cache.CacheControllerDispatcher;
import com.ning.billing.util.callcontext.CallContextFactory;
import com.ning.billing.util.callcontext.DefaultCallContextFactory;
import com.ning.billing.util.callcontext.InternalCallContextFactory;
@@ -59,11 +60,15 @@ import com.ning.billing.util.config.CatalogConfig;
import com.ning.billing.util.config.InvoiceConfig;
import com.ning.billing.util.customfield.dao.CustomFieldDao;
import com.ning.billing.util.customfield.dao.DefaultCustomFieldDao;
+import com.ning.billing.util.dao.DefaultNonEntityDao;
+import com.ning.billing.util.dao.NonEntityDao;
import com.ning.billing.util.email.EmailModule;
import com.ning.billing.util.email.templates.TemplateModule;
import com.ning.billing.util.globallocker.GlobalLocker;
import com.ning.billing.util.globallocker.MySqlGlobalLocker;
import com.ning.billing.util.glue.BusModule;
+import com.ning.billing.util.glue.CacheModule;
+import com.ning.billing.util.glue.NonEntityDaoModule;
import com.ning.billing.util.glue.NotificationQueueModule;
import com.ning.billing.util.glue.TagStoreModule;
import com.ning.billing.util.notificationq.NotificationQueueService;
@@ -95,7 +100,7 @@ public class TestOverdueCheckNotifier extends OverdueTestSuiteWithEmbeddedDB {
UUID latestSubscriptionId = null;
public OverdueListenerMock() {
- super(null, new InternalCallContextFactory(getDBI(), new ClockMock()));
+ super(null, new InternalCallContextFactory(new ClockMock(), new DefaultNonEntityDao(getDBI()), new CacheControllerDispatcher()));
}
@Override
@@ -136,6 +141,8 @@ public class TestOverdueCheckNotifier extends OverdueTestSuiteWithEmbeddedDB {
install(new EmailModule());
install(new TemplateModule());
install(new NotificationQueueModule());
+ install(new CacheModule());
+ install(new NonEntityDaoModule());
final AccountInternalApi accountApi = Mockito.mock(AccountInternalApi.class);
bind(AccountInternalApi.class).toInstance(accountApi);
diff --git a/overdue/src/test/java/com/ning/billing/overdue/OverdueTestBase.java b/overdue/src/test/java/com/ning/billing/overdue/OverdueTestBase.java
index e6a3a8e..936c074 100644
--- a/overdue/src/test/java/com/ning/billing/overdue/OverdueTestBase.java
+++ b/overdue/src/test/java/com/ning/billing/overdue/OverdueTestBase.java
@@ -58,7 +58,9 @@ import com.ning.billing.util.callcontext.InternalTenantContext;
import com.ning.billing.util.clock.ClockMock;
import com.ning.billing.util.email.EmailModule;
import com.ning.billing.util.email.templates.TemplateModule;
+import com.ning.billing.util.glue.CacheModule;
import com.ning.billing.util.glue.CallContextModule;
+import com.ning.billing.util.glue.NonEntityDaoModule;
import com.ning.billing.util.glue.NotificationQueueModule;
import com.ning.billing.util.glue.TagStoreModule;
import com.ning.billing.util.notificationq.NotificationQueueService.NotificationQueueAlreadyExists;
@@ -72,7 +74,8 @@ import com.google.inject.Inject;
@Guice(modules = {DefaultOverdueModule.class, OverdueListenerTesterModule.class, MockClockModule.class, ApplicatorMockJunctionModule.class,
CallContextModule.class, CatalogModule.class, MockInvoiceModule.class, MockPaymentModule.class, NotificationQueueModule.class,
- EmailModule.class, TemplateModule.class, TestDbiModule.class, TagStoreModule.class, MockEntitlementModule.class, MockInvoiceModule.class, MockAccountModule.class})
+ EmailModule.class, TemplateModule.class, TestDbiModule.class, MockEntitlementModule.class, MockInvoiceModule.class,
+ MockAccountModule.class, CacheModule.class, NonEntityDaoModule.class, TagStoreModule.class})
public abstract class OverdueTestBase extends OverdueTestSuiteWithEmbeddedDB {
protected final String configXml =
"<overdueConfig>" +
diff --git a/payment/src/main/java/com/ning/billing/payment/dao/DefaultPaymentDao.java b/payment/src/main/java/com/ning/billing/payment/dao/DefaultPaymentDao.java
index 381fd3b..8456706 100644
--- a/payment/src/main/java/com/ning/billing/payment/dao/DefaultPaymentDao.java
+++ b/payment/src/main/java/com/ning/billing/payment/dao/DefaultPaymentDao.java
@@ -27,8 +27,11 @@ import org.skife.jdbi.v2.IDBI;
import com.ning.billing.payment.api.PaymentStatus;
import com.ning.billing.payment.dao.RefundModelDao.RefundStatus;
+import com.ning.billing.util.cache.CacheControllerDispatcher;
import com.ning.billing.util.callcontext.InternalCallContext;
import com.ning.billing.util.callcontext.InternalTenantContext;
+import com.ning.billing.util.clock.Clock;
+import com.ning.billing.util.dao.NonEntityDao;
import com.ning.billing.util.entity.EntityPersistenceException;
import com.ning.billing.util.entity.dao.EntitySqlDao;
import com.ning.billing.util.entity.dao.EntitySqlDaoTransactionWrapper;
@@ -41,8 +44,8 @@ public class DefaultPaymentDao implements PaymentDao {
private final EntitySqlDaoTransactionalJdbiWrapper transactionalSqlDao;
@Inject
- public DefaultPaymentDao(final IDBI dbi) {
- this.transactionalSqlDao = new EntitySqlDaoTransactionalJdbiWrapper(dbi);
+ public DefaultPaymentDao(final IDBI dbi, final Clock clock, final CacheControllerDispatcher cacheControllerDispatcher, final NonEntityDao nonEntityDao) {
+ this.transactionalSqlDao = new EntitySqlDaoTransactionalJdbiWrapper(dbi, clock, cacheControllerDispatcher, nonEntityDao);
}
@Override
diff --git a/payment/src/main/java/com/ning/billing/payment/dao/PaymentAttemptModelDao.java b/payment/src/main/java/com/ning/billing/payment/dao/PaymentAttemptModelDao.java
index 5defd47..63aaaa6 100644
--- a/payment/src/main/java/com/ning/billing/payment/dao/PaymentAttemptModelDao.java
+++ b/payment/src/main/java/com/ning/billing/payment/dao/PaymentAttemptModelDao.java
@@ -178,4 +178,10 @@ public class PaymentAttemptModelDao extends EntityBase implements EntityModelDao
public TableName getTableName() {
return TableName.PAYMENT_ATTEMPTS;
}
+
+ @Override
+ public TableName getHistoryTableName() {
+ return TableName.PAYMENT_ATTEMPT_HISTORY;
+ }
+
}
diff --git a/payment/src/main/java/com/ning/billing/payment/dao/PaymentMethodModelDao.java b/payment/src/main/java/com/ning/billing/payment/dao/PaymentMethodModelDao.java
index 9f3fc4f..9287a57 100644
--- a/payment/src/main/java/com/ning/billing/payment/dao/PaymentMethodModelDao.java
+++ b/payment/src/main/java/com/ning/billing/payment/dao/PaymentMethodModelDao.java
@@ -128,4 +128,10 @@ public class PaymentMethodModelDao extends EntityBase implements EntityModelDao<
public TableName getTableName() {
return TableName.PAYMENT_METHODS;
}
+
+ @Override
+ public TableName getHistoryTableName() {
+ return TableName.PAYMENT_METHOD_HISTORY;
+ }
+
}
diff --git a/payment/src/main/java/com/ning/billing/payment/dao/PaymentModelDao.java b/payment/src/main/java/com/ning/billing/payment/dao/PaymentModelDao.java
index ab6d409..4d409c1 100644
--- a/payment/src/main/java/com/ning/billing/payment/dao/PaymentModelDao.java
+++ b/payment/src/main/java/com/ning/billing/payment/dao/PaymentModelDao.java
@@ -205,4 +205,10 @@ public class PaymentModelDao extends EntityBase implements EntityModelDao<Paymen
public TableName getTableName() {
return TableName.PAYMENTS;
}
+
+ @Override
+ public TableName getHistoryTableName() {
+ return TableName.PAYMENT_HISTORY;
+ }
+
}
diff --git a/payment/src/main/java/com/ning/billing/payment/dao/RefundModelDao.java b/payment/src/main/java/com/ning/billing/payment/dao/RefundModelDao.java
index 22c90eb..b861511 100644
--- a/payment/src/main/java/com/ning/billing/payment/dao/RefundModelDao.java
+++ b/payment/src/main/java/com/ning/billing/payment/dao/RefundModelDao.java
@@ -165,4 +165,10 @@ public class RefundModelDao extends EntityBase implements EntityModelDao<Refund>
public TableName getTableName() {
return TableName.REFUNDS;
}
+
+ @Override
+ public TableName getHistoryTableName() {
+ return TableName.REFUND_HISTORY;
+ }
+
}
diff --git a/payment/src/test/java/com/ning/billing/payment/api/TestPaymentApi.java b/payment/src/test/java/com/ning/billing/payment/api/TestPaymentApi.java
index 8224949..27c1399 100644
--- a/payment/src/test/java/com/ning/billing/payment/api/TestPaymentApi.java
+++ b/payment/src/test/java/com/ning/billing/payment/api/TestPaymentApi.java
@@ -37,6 +37,7 @@ import com.ning.billing.catalog.api.Currency;
import com.ning.billing.invoice.api.Invoice;
import com.ning.billing.mock.glue.MockClockModule;
import com.ning.billing.mock.glue.MockJunctionModule;
+import com.ning.billing.mock.glue.MockNonEntityDaoModule;
import com.ning.billing.payment.MockRecurringInvoiceItem;
import com.ning.billing.payment.PaymentTestSuite;
import com.ning.billing.payment.TestHelper;
@@ -44,7 +45,9 @@ import com.ning.billing.payment.api.Payment.PaymentAttempt;
import com.ning.billing.payment.glue.PaymentTestModuleWithMocks;
import com.ning.billing.payment.provider.DefaultNoOpPaymentMethodPlugin;
import com.ning.billing.util.clock.Clock;
+import com.ning.billing.util.glue.CacheModule;
import com.ning.billing.util.glue.CallContextModule;
+import com.ning.billing.util.glue.NonEntityDaoModule;
import com.ning.billing.util.svcapi.account.AccountInternalApi;
import com.ning.billing.util.svcsapi.bus.InternalBus;
import com.ning.billing.util.svcsapi.bus.InternalBus.EventBusException;
@@ -56,7 +59,7 @@ import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertTrue;
import static org.testng.Assert.fail;
-@Guice(modules = {PaymentTestModuleWithMocks.class, MockClockModule.class, MockJunctionModule.class, CallContextModule.class})
+@Guice(modules = {PaymentTestModuleWithMocks.class, MockClockModule.class, MockJunctionModule.class, CacheModule.class, MockNonEntityDaoModule.class, CallContextModule.class})
public class TestPaymentApi extends PaymentTestSuite {
private static final Logger log = LoggerFactory.getLogger(TestPaymentApi.class);
diff --git a/payment/src/test/java/com/ning/billing/payment/dao/TestPaymentDao.java b/payment/src/test/java/com/ning/billing/payment/dao/TestPaymentDao.java
index bf50c4c..a55e42b 100644
--- a/payment/src/test/java/com/ning/billing/payment/dao/TestPaymentDao.java
+++ b/payment/src/test/java/com/ning/billing/payment/dao/TestPaymentDao.java
@@ -36,8 +36,10 @@ import com.ning.billing.dbi.DbiConfig;
import com.ning.billing.payment.PaymentTestSuiteWithEmbeddedDB;
import com.ning.billing.payment.api.PaymentStatus;
import com.ning.billing.payment.dao.RefundModelDao.RefundStatus;
+import com.ning.billing.util.cache.CacheControllerDispatcher;
import com.ning.billing.util.clock.Clock;
import com.ning.billing.util.clock.DefaultClock;
+import com.ning.billing.util.dao.DefaultNonEntityDao;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
@@ -50,12 +52,15 @@ public class TestPaymentDao extends PaymentTestSuiteWithEmbeddedDB {
private DBTestingHelper helper;
private IDBI dbi;
private Clock clock;
+ private CacheControllerDispatcher controllerDispatcher;
+
@BeforeSuite(groups = "slow")
public void setup() throws IOException {
clock = new DefaultClock();
+ controllerDispatcher = new CacheControllerDispatcher();
setupDb();
- paymentDao = new DefaultPaymentDao(dbi);
+ paymentDao = new DefaultPaymentDao(dbi, clock, controllerDispatcher, new DefaultNonEntityDao(dbi));
}
private void setupDb() {
diff --git a/payment/src/test/java/com/ning/billing/payment/glue/PaymentTestModuleWithMocks.java b/payment/src/test/java/com/ning/billing/payment/glue/PaymentTestModuleWithMocks.java
index 0da7d2b..2bc60f0 100644
--- a/payment/src/test/java/com/ning/billing/payment/glue/PaymentTestModuleWithMocks.java
+++ b/payment/src/test/java/com/ning/billing/payment/glue/PaymentTestModuleWithMocks.java
@@ -31,9 +31,7 @@ import com.ning.billing.mock.glue.MockNotificationQueueModule;
import com.ning.billing.payment.dao.MockPaymentDao;
import com.ning.billing.payment.dao.PaymentDao;
import com.ning.billing.payment.provider.MockPaymentProviderPluginModule;
-import com.ning.billing.util.callcontext.CallContextSqlDao;
import com.ning.billing.util.callcontext.InternalTenantContext;
-import com.ning.billing.util.callcontext.MockCallContextSqlDao;
import com.ning.billing.util.config.PaymentConfig;
import com.ning.billing.util.globallocker.GlobalLocker;
import com.ning.billing.util.globallocker.MockGlobalLocker;
@@ -71,7 +69,6 @@ public class PaymentTestModuleWithMocks extends PaymentModule {
@Override
protected void installPaymentDao() {
final IDBI idbi = Mockito.mock(IDBI.class);
- Mockito.when(idbi.onDemand(CallContextSqlDao.class)).thenReturn(new MockCallContextSqlDao());
bind(IDBI.class).toInstance(idbi);
bind(PaymentDao.class).to(MockPaymentDao.class).asEagerSingleton();
}
diff --git a/payment/src/test/java/com/ning/billing/payment/TestRetryService.java b/payment/src/test/java/com/ning/billing/payment/TestRetryService.java
index 80d84e5..3ca7eb4 100644
--- a/payment/src/test/java/com/ning/billing/payment/TestRetryService.java
+++ b/payment/src/test/java/com/ning/billing/payment/TestRetryService.java
@@ -32,6 +32,7 @@ import org.testng.annotations.Test;
import com.ning.billing.account.api.Account;
import com.ning.billing.catalog.api.Currency;
+import com.ning.billing.mock.glue.MockNonEntityDaoModule;
import com.ning.billing.util.config.PaymentConfig;
import com.ning.billing.invoice.api.Invoice;
import com.ning.billing.mock.glue.MockClockModule;
@@ -48,7 +49,9 @@ import com.ning.billing.payment.provider.PaymentProviderPluginRegistry;
import com.ning.billing.payment.retry.FailedPaymentRetryService;
import com.ning.billing.payment.retry.PluginFailureRetryService;
import com.ning.billing.util.clock.ClockMock;
+import com.ning.billing.util.glue.CacheModule;
import com.ning.billing.util.glue.CallContextModule;
+import com.ning.billing.util.glue.NonEntityDaoModule;
import com.ning.billing.util.svcapi.invoice.InvoiceInternalApi;
import com.ning.billing.util.svcsapi.bus.InternalBus;
@@ -60,7 +63,7 @@ import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
import static org.testng.Assert.fail;
-@Guice(modules = {PaymentTestModuleWithMocks.class, MockClockModule.class, MockJunctionModule.class, CallContextModule.class})
+@Guice(modules = {PaymentTestModuleWithMocks.class, MockClockModule.class, MockJunctionModule.class, CacheModule.class, CallContextModule.class, MockNonEntityDaoModule.class})
public class TestRetryService extends PaymentTestSuite {
@Inject
private PaymentConfig paymentConfig;
pom.xml 8(+8 -0)
diff --git a/pom.xml b/pom.xml
index 0358af0..a5abb2b 100644
--- a/pom.xml
+++ b/pom.xml
@@ -36,6 +36,7 @@
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<slf4j.version>1.6.5</slf4j.version>
+ <ehcache.version>2.6.2</ehcache.version>
</properties>
<modules>
<module>account</module>
@@ -58,6 +59,12 @@
<dependencyManagement>
<dependencies>
<dependency>
+ <groupId>net.sf.ehcache</groupId>
+ <artifactId>ehcache-core</artifactId>
+ <version>${ehcache.version}</version>
+ <type>jar</type>
+ </dependency>
+ <dependency>
<groupId>javax.ws.rs</groupId>
<artifactId>jsr311-api</artifactId>
<version>1.1.1</version>
@@ -494,6 +501,7 @@
<!-- For some reason, useIdeaDefaultExcludes
doesn't pick up .idea directory -->
<exclude>.idea/**</exclude>
+ <exclude>**/*.iml</exclude>
<exclude>**/.project</exclude>
<exclude>.git/**</exclude>
<exclude>.gitignore</exclude>
diff --git a/server/src/main/java/com/ning/billing/server/listeners/KillbillGuiceListener.java b/server/src/main/java/com/ning/billing/server/listeners/KillbillGuiceListener.java
index 15c9b9a..bbb7d5f 100644
--- a/server/src/main/java/com/ning/billing/server/listeners/KillbillGuiceListener.java
+++ b/server/src/main/java/com/ning/billing/server/listeners/KillbillGuiceListener.java
@@ -16,6 +16,9 @@
package com.ning.billing.server.listeners;
+import java.lang.management.ManagementFactory;
+
+import javax.management.MBeanServer;
import javax.servlet.ServletContextEvent;
import org.slf4j.Logger;
@@ -36,6 +39,8 @@ import com.ning.jetty.core.listeners.SetupServer;
import com.google.inject.Injector;
import com.google.inject.Module;
+import net.sf.ehcache.CacheManager;
+import net.sf.ehcache.management.ManagementService;
public class KillbillGuiceListener extends SetupServer {
@@ -50,6 +55,13 @@ public class KillbillGuiceListener extends SetupServer {
return new KillbillServerModule();
}
+ private void registerMBeansForCache(final CacheManager cacheManager) {
+ if (cacheManager != null) {
+ final MBeanServer mBeanServer = ManagementFactory.getPlatformMBeanServer();
+ ManagementService.registerMBeans(cacheManager, mBeanServer, false, true, true, true);
+ }
+ }
+
@Override
public void contextInitialized(final ServletContextEvent event) {
final boolean multitenant = Boolean.parseBoolean(System.getProperty(KILLBILL_MULTITENANT_PROPERTY, "false"));
@@ -79,6 +91,8 @@ public class KillbillGuiceListener extends SetupServer {
killbillBusService = theInjector.getInstance(BusService.class);
killbilleventHandler = theInjector.getInstance(KillbillEventHandler.class);
+ registerMBeansForCache(theInjector.getInstance(CacheManager.class));
+
/*
ObjectMapper mapper = theInjector.getInstance(ObjectMapper.class);
mapper.setPropertyNamingStrategy(new PropertyNamingStrategy.LowerCaseWithUnderscoresStrategy());
diff --git a/server/src/main/java/com/ning/billing/server/modules/KillbillServerModule.java b/server/src/main/java/com/ning/billing/server/modules/KillbillServerModule.java
index 73e24ba..86779b0 100644
--- a/server/src/main/java/com/ning/billing/server/modules/KillbillServerModule.java
+++ b/server/src/main/java/com/ning/billing/server/modules/KillbillServerModule.java
@@ -49,11 +49,13 @@ import com.ning.billing.util.email.EmailModule;
import com.ning.billing.util.email.templates.TemplateModule;
import com.ning.billing.util.glue.AuditModule;
import com.ning.billing.util.glue.BusModule;
+import com.ning.billing.util.glue.CacheModule;
import com.ning.billing.util.glue.CallContextModule;
import com.ning.billing.util.glue.ClockModule;
import com.ning.billing.util.glue.CustomFieldModule;
import com.ning.billing.util.glue.ExportModule;
import com.ning.billing.util.glue.GlobalLockerModule;
+import com.ning.billing.util.glue.NonEntityDaoModule;
import com.ning.billing.util.glue.NotificationQueueModule;
import com.ning.billing.util.glue.TagStoreModule;
@@ -105,6 +107,7 @@ public class KillbillServerModule extends AbstractModule {
protected void installKillbillModules() {
install(new EmailModule());
+ install(new CacheModule());
install(new GlobalLockerModule());
install(new CustomFieldModule());
install(new AuditModule());
@@ -125,6 +128,7 @@ public class KillbillServerModule extends AbstractModule {
install(new ExportModule());
install(new MeterModule());
install(new TagStoreModule());
+ install(new NonEntityDaoModule());
installClock();
}
}
server/src/main/resources/ehcache.xml 67(+67 -0)
diff --git a/server/src/main/resources/ehcache.xml b/server/src/main/resources/ehcache.xml
new file mode 100644
index 0000000..ac86fe3
--- /dev/null
+++ b/server/src/main/resources/ehcache.xml
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+ ~ Copyright 2010-2012 Ning, Inc.
+ ~
+ ~ Ning licenses this file to you under the Apache License, version 2.0
+ ~ (the "License"); you may not use this file except in compliance with the
+ ~ License. You may obtain a copy of the License at:
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ ~ WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ ~ License for the specific language governing permissions and limitations
+ ~ under the License.
+ -->
+
+<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:noNamespaceSchemaLocation="ehcache.xsd" >
+
+ <defaultCache
+ maxElementsInMemory="0"
+ maxElementsOnDisk="0"
+ eternal="false"
+ timeToIdleSeconds="0"
+ timeToLiveSeconds="0"
+ overflowToDisk="false"
+ />
+
+ <cache name="record-id"
+ maxElementsInMemory="100000"
+ maxElementsOnDisk="0"
+ eternal="true"
+ overflowToDisk="false"
+ diskPersistent="false"
+ memoryStoreEvictionPolicy="LFU">
+ <cacheEventListenerFactory
+ class="com.ning.billing.util.cache.ExpirationListenerFactory"
+ properties="" />
+ </cache>
+
+ <cache name="tenant-record-id"
+ maxElementsInMemory="100000"
+ maxElementsOnDisk="0"
+ eternal="true"
+ overflowToDisk="false"
+ diskPersistent="false"
+ memoryStoreEvictionPolicy="LFU">
+ <cacheEventListenerFactory
+ class="com.ning.billing.util.cache.ExpirationListenerFactory"
+ properties="" />
+ </cache>
+
+ <cache name="account-record-id"
+ maxElementsInMemory="100000"
+ maxElementsOnDisk="0"
+ eternal="true"
+ overflowToDisk="false"
+ diskPersistent="false"
+ memoryStoreEvictionPolicy="LFU">
+ <cacheEventListenerFactory
+ class="com.ning.billing.util.cache.ExpirationListenerFactory"
+ properties="" />
+ </cache>
+</ehcache>
+
diff --git a/server/src/test/java/com/ning/billing/jaxrs/TestJaxrsBase.java b/server/src/test/java/com/ning/billing/jaxrs/TestJaxrsBase.java
index 715a310..d8dca6b 100644
--- a/server/src/test/java/com/ning/billing/jaxrs/TestJaxrsBase.java
+++ b/server/src/test/java/com/ning/billing/jaxrs/TestJaxrsBase.java
@@ -62,9 +62,11 @@ import com.ning.billing.util.email.templates.TemplateModule;
import com.ning.billing.util.globallocker.TestGlobalLockerModule;
import com.ning.billing.util.glue.AuditModule;
import com.ning.billing.util.glue.BusModule;
+import com.ning.billing.util.glue.CacheModule;
import com.ning.billing.util.glue.CallContextModule;
import com.ning.billing.util.glue.CustomFieldModule;
import com.ning.billing.util.glue.ExportModule;
+import com.ning.billing.util.glue.NonEntityDaoModule;
import com.ning.billing.util.glue.NotificationQueueModule;
import com.ning.billing.util.glue.TagStoreModule;
import com.ning.http.client.AsyncHttpClient;
@@ -166,6 +168,8 @@ public class TestJaxrsBase extends KillbillClient {
Modules.override(new com.ning.billing.payment.setup.PaymentModule()).with(new PaymentMockModule());
*/
install(new EmailModule());
+ install(new CacheModule());
+ install(new NonEntityDaoModule());
install(new TestGlobalLockerModule(helper));
install(new CustomFieldModule());
install(new TagStoreModule());
diff --git a/server/src/test/java/com/ning/billing/server/security/TestKillbillJdbcRealm.java b/server/src/test/java/com/ning/billing/server/security/TestKillbillJdbcRealm.java
index ed0304b..6cd22b7 100644
--- a/server/src/test/java/com/ning/billing/server/security/TestKillbillJdbcRealm.java
+++ b/server/src/test/java/com/ning/billing/server/security/TestKillbillJdbcRealm.java
@@ -33,6 +33,8 @@ import com.ning.billing.server.ServerTestSuiteWithEmbeddedDB;
import com.ning.billing.tenant.api.DefaultTenant;
import com.ning.billing.tenant.dao.DefaultTenantDao;
import com.ning.billing.tenant.dao.TenantModelDao;
+import com.ning.billing.util.cache.CacheControllerDispatcher;
+import com.ning.billing.util.dao.DefaultNonEntityDao;
import com.jolbox.bonecp.BoneCPConfig;
import com.jolbox.bonecp.BoneCPDataSource;
@@ -45,7 +47,8 @@ public class TestKillbillJdbcRealm extends ServerTestSuiteWithEmbeddedDB {
@BeforeMethod(groups = "slow")
public void setUp() throws Exception {
// Create the tenant
- final DefaultTenantDao tenantDao = new DefaultTenantDao(getDBI());
+ final CacheControllerDispatcher controllerDispatcher = new CacheControllerDispatcher();
+ final DefaultTenantDao tenantDao = new DefaultTenantDao(getDBI(), clock, controllerDispatcher, new DefaultNonEntityDao(getDBI()));
tenant = new DefaultTenant(UUID.randomUUID(), null, null, UUID.randomUUID().toString(),
UUID.randomUUID().toString(), UUID.randomUUID().toString());
tenantDao.create(new TenantModelDao(tenant), internalCallContext);
server/src/test/resources/shiro.ini 3(+2 -1)
diff --git a/server/src/test/resources/shiro.ini b/server/src/test/resources/shiro.ini
index 21defe1..664ee13 100644
--- a/server/src/test/resources/shiro.ini
+++ b/server/src/test/resources/shiro.ini
@@ -33,4 +33,5 @@ jdbcRealm=com.ning.billing.server.security.KillbillJdbcRealm
/1.0/kb/tenants/** = anon
# For all other resources, require basic auth
# TODO: ssl, authcBasic
-/1.0/kb/** = authcBasic
+# Commented out because that seems to break the server tests that don't require authentification
+#/1.0/kb/** = authcBasic
diff --git a/tenant/src/main/java/com/ning/billing/tenant/dao/DefaultTenantDao.java b/tenant/src/main/java/com/ning/billing/tenant/dao/DefaultTenantDao.java
index 959d8bd..7e8d901 100644
--- a/tenant/src/main/java/com/ning/billing/tenant/dao/DefaultTenantDao.java
+++ b/tenant/src/main/java/com/ning/billing/tenant/dao/DefaultTenantDao.java
@@ -32,8 +32,11 @@ import com.ning.billing.ErrorCode;
import com.ning.billing.tenant.api.Tenant;
import com.ning.billing.tenant.api.TenantApiException;
import com.ning.billing.tenant.security.KillbillCredentialsMatcher;
+import com.ning.billing.util.cache.CacheControllerDispatcher;
import com.ning.billing.util.callcontext.InternalCallContext;
import com.ning.billing.util.callcontext.InternalTenantContext;
+import com.ning.billing.util.clock.Clock;
+import com.ning.billing.util.dao.NonEntityDao;
import com.ning.billing.util.entity.dao.EntityDaoBase;
import com.ning.billing.util.entity.dao.EntitySqlDao;
import com.ning.billing.util.entity.dao.EntitySqlDaoTransactionWrapper;
@@ -51,8 +54,8 @@ public class DefaultTenantDao extends EntityDaoBase<TenantModelDao, Tenant, Tena
private final RandomNumberGenerator rng = new SecureRandomNumberGenerator();
@Inject
- public DefaultTenantDao(final IDBI dbi) {
- super(new EntitySqlDaoTransactionalJdbiWrapper(dbi), TenantSqlDao.class);
+ public DefaultTenantDao(final IDBI dbi, final Clock clock, final CacheControllerDispatcher cacheControllerDispatcher, final NonEntityDao nonEntityDao) {
+ super(new EntitySqlDaoTransactionalJdbiWrapper(dbi, clock, cacheControllerDispatcher, nonEntityDao), TenantSqlDao.class);
}
@Override
diff --git a/tenant/src/main/java/com/ning/billing/tenant/dao/TenantKVModelDao.java b/tenant/src/main/java/com/ning/billing/tenant/dao/TenantKVModelDao.java
index 362bbbe..cae8cac 100644
--- a/tenant/src/main/java/com/ning/billing/tenant/dao/TenantKVModelDao.java
+++ b/tenant/src/main/java/com/ning/billing/tenant/dao/TenantKVModelDao.java
@@ -104,4 +104,9 @@ public class TenantKVModelDao extends EntityBase implements EntityModelDao<Tenan
public TableName getTableName() {
return TableName.TENANT_KVS;
}
+
+ @Override
+ public TableName getHistoryTableName() {
+ return null;
+ }
}
diff --git a/tenant/src/main/java/com/ning/billing/tenant/dao/TenantModelDao.java b/tenant/src/main/java/com/ning/billing/tenant/dao/TenantModelDao.java
index 6422373..6163351 100644
--- a/tenant/src/main/java/com/ning/billing/tenant/dao/TenantModelDao.java
+++ b/tenant/src/main/java/com/ning/billing/tenant/dao/TenantModelDao.java
@@ -120,4 +120,9 @@ public class TenantModelDao extends EntityBase implements EntityModelDao<Tenant>
public TableName getTableName() {
return TableName.TENANT;
}
+
+ @Override
+ public TableName getHistoryTableName() {
+ return null;
+ }
}
diff --git a/tenant/src/test/java/com/ning/billing/tenant/dao/TestDefaultTenantDao.java b/tenant/src/test/java/com/ning/billing/tenant/dao/TestDefaultTenantDao.java
index b8594bf..e3569e9 100644
--- a/tenant/src/test/java/com/ning/billing/tenant/dao/TestDefaultTenantDao.java
+++ b/tenant/src/test/java/com/ning/billing/tenant/dao/TestDefaultTenantDao.java
@@ -28,12 +28,16 @@ import org.testng.annotations.Test;
import com.ning.billing.tenant.TenantTestSuiteWithEmbeddedDb;
import com.ning.billing.tenant.api.DefaultTenant;
import com.ning.billing.tenant.security.KillbillCredentialsMatcher;
+import com.ning.billing.util.cache.CacheControllerDispatcher;
+import com.ning.billing.util.dao.DefaultNonEntityDao;
public class TestDefaultTenantDao extends TenantTestSuiteWithEmbeddedDb {
+ private CacheControllerDispatcher controllerDispatcher = new CacheControllerDispatcher();
+
@Test(groups = "slow")
public void testWeCanStoreAndMatchCredentials() throws Exception {
- final DefaultTenantDao tenantDao = new DefaultTenantDao(getDBI());
+ final DefaultTenantDao tenantDao = new DefaultTenantDao(getDBI(), clock, controllerDispatcher, new DefaultNonEntityDao(getDBI()));
final DefaultTenant tenant = new DefaultTenant(UUID.randomUUID(), null, null, UUID.randomUUID().toString(),
UUID.randomUUID().toString(), UUID.randomUUID().toString());
@@ -56,7 +60,7 @@ public class TestDefaultTenantDao extends TenantTestSuiteWithEmbeddedDb {
@Test(groups = "slow")
public void testTenantKeyValue() throws Exception {
- final DefaultTenantDao tenantDao = new DefaultTenantDao(getDBI());
+ final DefaultTenantDao tenantDao = new DefaultTenantDao(getDBI(), clock, controllerDispatcher, new DefaultNonEntityDao(getDBI()));
final DefaultTenant tenant = new DefaultTenant(UUID.randomUUID(), null, null, UUID.randomUUID().toString(),
UUID.randomUUID().toString(), UUID.randomUUID().toString());
tenantDao.create(new TenantModelDao(tenant), internalCallContext);
util/pom.xml 5(+5 -0)
diff --git a/util/pom.xml b/util/pom.xml
index 2a1a92a..cf9e5bb 100644
--- a/util/pom.xml
+++ b/util/pom.xml
@@ -25,6 +25,11 @@
<artifactId>killbill-api</artifactId>
</dependency>
<dependency>
+ <groupId>net.sf.ehcache</groupId>
+ <artifactId>ehcache-core</artifactId>
+ <type>jar</type>
+ </dependency>
+ <dependency>
<groupId>com.jolbox</groupId>
<artifactId>bonecp</artifactId>
</dependency>
diff --git a/util/src/main/java/com/ning/billing/util/cache/AccountRecordIdCacheLoader.java b/util/src/main/java/com/ning/billing/util/cache/AccountRecordIdCacheLoader.java
new file mode 100644
index 0000000..9bc5a75
--- /dev/null
+++ b/util/src/main/java/com/ning/billing/util/cache/AccountRecordIdCacheLoader.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2010-2013 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.util.cache;
+
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+
+import javax.inject.Inject;
+
+import org.skife.jdbi.v2.Handle;
+import org.skife.jdbi.v2.IDBI;
+import org.skife.jdbi.v2.tweak.HandleCallback;
+
+import com.ning.billing.ObjectType;
+import com.ning.billing.util.cache.Cachable.CacheType;
+import com.ning.billing.util.dao.NonEntityDao;
+import com.ning.billing.util.dao.TableName;
+
+import net.sf.ehcache.loader.CacheLoader;
+
+public class AccountRecordIdCacheLoader extends BaseCacheLoader implements CacheLoader {
+
+ @Inject
+ public AccountRecordIdCacheLoader(final IDBI dbi, final NonEntityDao nonEntityDao) {
+ super(dbi, nonEntityDao);
+ }
+
+ @Override
+ public Object load(final Object key, final Object argument) {
+
+ checkCacheLoaderStatus();
+
+ if (!(argument instanceof ObjectType)) {
+ throw new IllegalArgumentException("Unexpected argument type of " +
+ argument != null ? argument.getClass().getName() : "null");
+ }
+ if (!(key instanceof String)) {
+ throw new IllegalArgumentException("Unexpected key type of " +
+ key != null ? key.getClass().getName() : "null");
+
+ }
+ final String objectId = (String) key;
+ final ObjectType objectType = (ObjectType) argument;
+ Long value = nonEntityDao.retrieveAccountRecordIdFromObject(UUID.fromString(objectId), objectType, null);
+ return value;
+ }
+}
diff --git a/util/src/main/java/com/ning/billing/util/cache/BaseCacheLoader.java b/util/src/main/java/com/ning/billing/util/cache/BaseCacheLoader.java
new file mode 100644
index 0000000..855fdef
--- /dev/null
+++ b/util/src/main/java/com/ning/billing/util/cache/BaseCacheLoader.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright 2010-2013 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.util.cache;
+
+import java.util.Collection;
+import java.util.Map;
+
+import javax.inject.Inject;
+
+import org.skife.jdbi.v2.IDBI;
+
+import com.ning.billing.util.dao.NonEntityDao;
+
+import net.sf.ehcache.CacheException;
+import net.sf.ehcache.Ehcache;
+import net.sf.ehcache.Status;
+import net.sf.ehcache.loader.CacheLoader;
+
+public abstract class BaseCacheLoader implements CacheLoader {
+
+ protected final IDBI dbi;
+ protected final NonEntityDao nonEntityDao;
+
+ private Status cacheLoaderStatus;
+
+ @Inject
+ public BaseCacheLoader(final IDBI dbi, final NonEntityDao nonEntityDao) {
+ this.dbi = dbi;
+ this.nonEntityDao = nonEntityDao;
+ this.cacheLoaderStatus = Status.STATUS_UNINITIALISED;
+ }
+
+ @Override
+ public abstract Object load(final Object key, final Object argument);
+
+
+ @Override
+ public Object load(final Object key) throws CacheException {
+ throw new IllegalStateException("Method load is not implemented ");
+ }
+
+ @Override
+ public Map loadAll(final Collection keys) {
+ throw new IllegalStateException("Method loadAll is not implemented ");
+ }
+
+ @Override
+ public Map loadAll(final Collection keys, final Object argument) {
+ throw new IllegalStateException("Method loadAll is not implemented ");
+ }
+
+ @Override
+ public String getName() {
+ return this.getClass().getName();
+ }
+
+ @Override
+ public CacheLoader clone(final Ehcache cache) throws CloneNotSupportedException {
+ throw new IllegalStateException("Method clone is not implemented ");
+ }
+
+ @Override
+ public void init() {
+ this.cacheLoaderStatus = Status.STATUS_ALIVE;
+ }
+
+ @Override
+ public void dispose() throws CacheException {
+ cacheLoaderStatus = Status.STATUS_SHUTDOWN;
+ }
+
+ @Override
+ public Status getStatus() {
+ return cacheLoaderStatus;
+ }
+
+ protected void checkCacheLoaderStatus() {
+ if (getStatus() != Status.STATUS_ALIVE) {
+ throw new CacheException("CacheLoader is not available!");
+ }
+ }
+}
diff --git a/util/src/main/java/com/ning/billing/util/cache/Cachable.java b/util/src/main/java/com/ning/billing/util/cache/Cachable.java
new file mode 100644
index 0000000..ac9e0ee
--- /dev/null
+++ b/util/src/main/java/com/ning/billing/util/cache/Cachable.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.util.cache;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.util.UUID;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.METHOD})
+public @interface Cachable {
+
+ public final String RECORD_ID_CACHE_NAME = "record-id";
+ public final String ACCOUNT_RECORD_ID_CACHE_NAME = "account-record-id";
+ public final String TENANT_RECORD_ID_CACHE_NAME = "tenant-record-id";
+
+ public CacheType value();
+
+ public enum CacheType {
+ /* Mapping from object 'id (UUID)' -> object 'recordId (Long' */
+ RECORD_ID(RECORD_ID_CACHE_NAME, UUID.class, Long.class),
+
+ /* Mapping from object 'id (UUID)' -> matching account object 'accountRecordId (Long)' */
+ ACCOUNT_RECORD_ID(ACCOUNT_RECORD_ID_CACHE_NAME, UUID.class, Long.class),
+
+
+ /* Mapping from object 'id (UUID)' -> matching object 'tenantRecordId (Long)' */
+ TENANT_RECORD_ID(TENANT_RECORD_ID_CACHE_NAME, UUID.class, Long.class);
+
+ private final String cacheName;
+ private final Class key;
+ private final Class value;
+
+ CacheType(final String cacheName, final Class key, final Class value) {
+ this.cacheName = cacheName;
+ this.key = key;
+ this.value = value;
+ }
+
+ public Class getKey() {
+ return key;
+ }
+
+ public Class getValue() {
+ return value;
+ }
+
+ public static CacheType findByName(final String input) {
+ for (CacheType cur : CacheType.values()) {
+ if (cur.cacheName.equals(input)) {
+ return cur;
+ }
+ }
+ return null;
+ }
+ }
+}
diff --git a/util/src/main/java/com/ning/billing/util/cache/CacheControllerDispatcher.java b/util/src/main/java/com/ning/billing/util/cache/CacheControllerDispatcher.java
new file mode 100644
index 0000000..ee9b3d0
--- /dev/null
+++ b/util/src/main/java/com/ning/billing/util/cache/CacheControllerDispatcher.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.util.cache;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
+import javax.inject.Inject;
+
+import com.ning.billing.util.cache.Cachable.CacheType;
+
+import com.google.inject.name.Named;
+
+public class CacheControllerDispatcher {
+
+ private final Map<CacheType, CacheController<?,?>> caches;
+
+ @Inject
+ public CacheControllerDispatcher(@Named(Cachable.RECORD_ID_CACHE_NAME) final CacheController<UUID, Long> recordIdCacheController,
+ @Named(Cachable.ACCOUNT_RECORD_ID_CACHE_NAME) final CacheController<UUID, Long> accountRecordIdCacheController,
+ @Named(Cachable.TENANT_RECORD_ID_CACHE_NAME) final CacheController<UUID, Long> tenantRecordIdCacheController) {
+ caches = new HashMap<CacheType, CacheController<?, ?>>();
+ caches.put(recordIdCacheController.getType(), recordIdCacheController);
+ caches.put(accountRecordIdCacheController.getType(), accountRecordIdCacheController);
+ caches.put(tenantRecordIdCacheController.getType(), tenantRecordIdCacheController);
+ }
+
+ // Test only
+ public CacheControllerDispatcher() {
+ caches = new HashMap<CacheType, CacheController<?, ?>>();
+ }
+
+ public <K,V> CacheController<K, V> getCacheController(CacheType cacheType) {
+ // STEPH Not the prettiest thing..
+ return CacheController.class.cast(caches.get(cacheType));
+ }
+}
diff --git a/util/src/main/java/com/ning/billing/util/cache/CacheControllerProvider.java b/util/src/main/java/com/ning/billing/util/cache/CacheControllerProvider.java
new file mode 100644
index 0000000..cc715e5
--- /dev/null
+++ b/util/src/main/java/com/ning/billing/util/cache/CacheControllerProvider.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.util.cache;
+
+
+import javax.inject.Inject;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.ning.billing.util.cache.Cachable.CacheType;
+
+import com.google.inject.Injector;
+import com.google.inject.Key;
+import com.google.inject.Provider;
+import com.google.inject.name.Names;
+import net.sf.ehcache.Cache;
+import net.sf.ehcache.CacheManager;
+import net.sf.ehcache.loader.CacheLoader;
+
+public class CacheControllerProvider<K,V> implements Provider<CacheController<K, V>> {
+
+ private final static Logger logger = LoggerFactory.getLogger(CacheControllerProvider.class);
+
+ private CacheManager cacheManager;
+ private final String name;
+
+ private Injector injector;
+
+ public CacheControllerProvider(final String name) {
+ this.name = name;
+ }
+
+ @Inject
+ public void configure(final Injector injector, final CacheManager cacheManager) {
+ this.injector = injector;
+ this.cacheManager = cacheManager;
+ }
+
+ @Override
+ public CacheController<K, V> get() {
+
+ final Cache cache = cacheManager.getCache(name);
+ final Key<CacheLoader> cacheLoaderKey = Key.get(CacheLoader.class, Names.named(name));
+ final CacheLoader cacheLoader = injector.getInstance(cacheLoaderKey);
+
+ cacheLoader.init();
+
+ cache.registerCacheLoader(cacheLoader);
+
+ return new EhCacheBasedCacheController<K, V>(cache, CacheType.findByName(name));
+ }
+}
diff --git a/util/src/main/java/com/ning/billing/util/cache/CacheManagerProvider.java b/util/src/main/java/com/ning/billing/util/cache/CacheManagerProvider.java
new file mode 100644
index 0000000..83a68a8
--- /dev/null
+++ b/util/src/main/java/com/ning/billing/util/cache/CacheManagerProvider.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.util.cache;
+
+import java.io.IOException;
+
+import javax.inject.Inject;
+import javax.inject.Provider;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.ning.billing.util.config.CacheConfig;
+
+import net.sf.ehcache.CacheManager;
+
+public class CacheManagerProvider implements Provider<CacheManager> {
+
+ private static final Logger log = LoggerFactory.getLogger(CacheManagerProvider.class);
+
+ private final CacheConfig cacheConfig;
+
+ private CacheManager cacheManager = null;
+
+ @Inject
+ public CacheManagerProvider(final CacheConfig cacheConfig) {
+ this.cacheConfig = cacheConfig;
+ }
+
+ @Override
+ public CacheManager get() {
+ synchronized (this) {
+ if (this.cacheManager == null) {
+ log.debug("Loading EHCache config from '%s'", cacheConfig.getCacheConfigLocation());
+
+ try {
+ // Creates a singleton instance of the CacheManager
+ this.cacheManager = CacheManager.create(CacheManagerProvider.class.getResource(cacheConfig.getCacheConfigLocation()).openStream());
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ return this.cacheManager;
+ }
+ }
+}
diff --git a/util/src/main/java/com/ning/billing/util/cache/EhCacheBasedCacheController.java b/util/src/main/java/com/ning/billing/util/cache/EhCacheBasedCacheController.java
new file mode 100644
index 0000000..623f1f7
--- /dev/null
+++ b/util/src/main/java/com/ning/billing/util/cache/EhCacheBasedCacheController.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.util.cache;
+
+import java.util.Collection;
+import java.util.Map;
+
+import com.ning.billing.ObjectType;
+import com.ning.billing.util.cache.Cachable.CacheType;
+
+import net.sf.ehcache.Cache;
+import net.sf.ehcache.Element;
+
+public class EhCacheBasedCacheController<K, V> implements CacheController<K, V> {
+
+ private final Cache cache;
+ private final CacheType cacheType;
+
+ public EhCacheBasedCacheController(final Cache cache, final CacheType cacheType) {
+ this.cache = cache;
+ this.cacheType = cacheType;
+ }
+
+ @Override
+ public CacheType getType() {
+ return cacheType;
+ }
+
+ @Override
+ public V get(final K key, final ObjectType objectType) {
+ final Element element = cache.getWithLoader(key, null, objectType);
+ if (element == null) {
+ return null;
+ }
+ return (V) element.getObjectValue();
+ }
+
+ @Override
+ public boolean remove(final K key) {
+ return cache.remove(key);
+ }
+
+ @Override
+ public int size() {
+ return cache.getSize();
+ }
+}
diff --git a/util/src/main/java/com/ning/billing/util/cache/ExpirationListenerFactory.java b/util/src/main/java/com/ning/billing/util/cache/ExpirationListenerFactory.java
new file mode 100644
index 0000000..f592aac
--- /dev/null
+++ b/util/src/main/java/com/ning/billing/util/cache/ExpirationListenerFactory.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.util.cache;
+
+import java.util.Properties;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import net.sf.ehcache.CacheException;
+import net.sf.ehcache.Ehcache;
+import net.sf.ehcache.Element;
+import net.sf.ehcache.event.CacheEventListener;
+import net.sf.ehcache.event.CacheEventListenerFactory;
+
+public class ExpirationListenerFactory extends CacheEventListenerFactory {
+
+ private static final Logger log = LoggerFactory.getLogger(ExpirationListenerFactory.class);
+
+ @Override
+ public CacheEventListener createCacheEventListener(final Properties properties)
+ {
+ return new ExpirationListener();
+ }
+
+ private static class ExpirationListener implements CacheEventListener
+ {
+ @Override
+ public Object clone() throws CloneNotSupportedException
+ {
+ throw new CloneNotSupportedException("No cloning!");
+ }
+
+ @Override
+ public void dispose()
+ {
+ }
+
+ @Override
+ public void notifyElementEvicted(final Ehcache cache, final Element element)
+ {
+ if (log.isDebugEnabled()) {
+ log.debug("Cache Element " + element + " evicted!");
+ }
+ }
+
+ @Override
+ public void notifyElementExpired(final Ehcache cache, final Element element)
+ {
+ if (log.isDebugEnabled()) {
+ log.debug("Cache Element " + element + " expired!");
+ }
+ }
+
+ @Override
+ public void notifyElementPut(final Ehcache cache, final Element element) throws CacheException
+ {
+ }
+
+ @Override
+ public void notifyElementRemoved(final Ehcache cache, final Element element) throws CacheException
+ {
+ }
+
+ @Override
+ public void notifyElementUpdated(final Ehcache cache, final Element element) throws CacheException
+ {
+ }
+
+ @Override
+ public void notifyRemoveAll(final Ehcache cache)
+ {
+ }
+ }
+}
diff --git a/util/src/main/java/com/ning/billing/util/cache/RecordIdCacheLoader.java b/util/src/main/java/com/ning/billing/util/cache/RecordIdCacheLoader.java
new file mode 100644
index 0000000..3489753
--- /dev/null
+++ b/util/src/main/java/com/ning/billing/util/cache/RecordIdCacheLoader.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.util.cache;
+
+import java.util.UUID;
+
+import javax.inject.Inject;
+
+import org.skife.jdbi.v2.IDBI;
+
+import com.ning.billing.ObjectType;
+import com.ning.billing.util.dao.NonEntityDao;
+
+import net.sf.ehcache.CacheException;
+import net.sf.ehcache.loader.CacheLoader;
+
+public class RecordIdCacheLoader extends BaseCacheLoader implements CacheLoader {
+
+ @Inject
+ public RecordIdCacheLoader(final IDBI dbi, final NonEntityDao nonEntityDao) {
+ super(dbi, nonEntityDao);
+ }
+
+ @Override
+ public Object load(final Object key, final Object argument) throws CacheException {
+
+ checkCacheLoaderStatus();
+
+ if (!(argument instanceof ObjectType)) {
+ throw new IllegalArgumentException("Unexpected argument type of " +
+ argument != null ? argument.getClass().getName() : "null");
+ }
+ if (!(key instanceof String)) {
+ throw new IllegalArgumentException("Unexpected key type of " +
+ key != null ? key.getClass().getName() : "null");
+
+ }
+ final String objectId = (String) key;
+ final ObjectType objectType = (ObjectType) argument;
+ Long value = nonEntityDao.retrieveRecordIdFromObject(UUID.fromString(objectId), objectType, null);
+ return value;
+ }
+}
diff --git a/util/src/main/java/com/ning/billing/util/cache/TenantRecordIdCacheLoader.java b/util/src/main/java/com/ning/billing/util/cache/TenantRecordIdCacheLoader.java
new file mode 100644
index 0000000..d8c2eb4
--- /dev/null
+++ b/util/src/main/java/com/ning/billing/util/cache/TenantRecordIdCacheLoader.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2010-2013 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.util.cache;
+
+import java.util.UUID;
+
+import javax.inject.Inject;
+
+import org.skife.jdbi.v2.IDBI;
+
+import com.ning.billing.ObjectType;
+import com.ning.billing.util.dao.NonEntityDao;
+
+import net.sf.ehcache.loader.CacheLoader;
+
+public class TenantRecordIdCacheLoader extends BaseCacheLoader implements CacheLoader {
+
+ @Inject
+ public TenantRecordIdCacheLoader(final IDBI dbi, final NonEntityDao nonEntityDao) {
+ super(dbi, nonEntityDao);
+ }
+
+ @Override
+ public Object load(final Object key, final Object argument) {
+
+ checkCacheLoaderStatus();
+
+ if (!(argument instanceof ObjectType)) {
+ throw new IllegalArgumentException("Unexpected argument type of " +
+ argument != null ? argument.getClass().getName() : "null");
+ }
+ if (!(key instanceof String)) {
+ throw new IllegalArgumentException("Unexpected key type of " +
+ key != null ? key.getClass().getName() : "null");
+
+ }
+ final String objectId = (String) key;
+ final ObjectType objectType = (ObjectType) argument;
+ Long value = nonEntityDao.retrieveTenantRecordIdFromObject(UUID.fromString(objectId), objectType, null);
+ return value;
+ }
+}
diff --git a/util/src/main/java/com/ning/billing/util/callcontext/InternalCallContextFactory.java b/util/src/main/java/com/ning/billing/util/callcontext/InternalCallContextFactory.java
index 500313b..5a61f63 100644
--- a/util/src/main/java/com/ning/billing/util/callcontext/InternalCallContextFactory.java
+++ b/util/src/main/java/com/ning/billing/util/callcontext/InternalCallContextFactory.java
@@ -16,21 +16,18 @@
package com.ning.billing.util.callcontext;
-import java.util.List;
-import java.util.Map;
import java.util.UUID;
import javax.annotation.Nullable;
import javax.inject.Inject;
import org.joda.time.DateTime;
-import org.skife.jdbi.v2.Handle;
-import org.skife.jdbi.v2.IDBI;
-import org.skife.jdbi.v2.tweak.HandleCallback;
import com.ning.billing.ObjectType;
+import com.ning.billing.util.cache.Cachable.CacheType;
+import com.ning.billing.util.cache.CacheControllerDispatcher;
import com.ning.billing.util.clock.Clock;
-import com.ning.billing.util.dao.TableName;
+import com.ning.billing.util.dao.NonEntityDao;
import com.google.common.base.Objects;
@@ -38,15 +35,18 @@ public class InternalCallContextFactory {
public static final long INTERNAL_TENANT_RECORD_ID = 0L;
- private final IDBI dbi;
private final Clock clock;
+ private final NonEntityDao nonEntityDao;
+ private final CacheControllerDispatcher cacheControllerDispatcher;
@Inject
- public InternalCallContextFactory(final IDBI dbi, final Clock clock) {
- this.dbi = dbi;
+ public InternalCallContextFactory(final Clock clock, final NonEntityDao nonEntityDao, final CacheControllerDispatcher cacheControllerDispatcher) {
this.clock = clock;
+ this.nonEntityDao = nonEntityDao;
+ this.cacheControllerDispatcher = cacheControllerDispatcher;
}
+
/**
* Create an internal tenant context from a tenant context
* <p/>
@@ -143,8 +143,8 @@ public class InternalCallContextFactory {
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 = retrieveTenantRecordIdFromObject(objectId, objectType);
- final Long accountRecordId = retrieveAccountRecordIdFromObject(objectId, objectType);
+ final Long tenantRecordId = nonEntityDao.retrieveTenantRecordIdFromObject(objectId, objectType, cacheControllerDispatcher.getCacheController(CacheType.TENANT_RECORD_ID));
+ final Long accountRecordId = nonEntityDao.retrieveAccountRecordIdFromObject(objectId, objectType, cacheControllerDispatcher.getCacheController(CacheType.ACCOUNT_RECORD_ID));
return createInternalCallContext(tenantRecordId, accountRecordId, userName, callOrigin, userType, userToken,
reasonCode, comment, createdDate, updatedDate);
}
@@ -213,76 +213,7 @@ public class InternalCallContextFactory {
if (context.getTenantId() == null) {
return INTERNAL_TENANT_RECORD_ID;
} else {
- // We call onDemand here to avoid JDBI opening connections in the constructor.
- // TODO should we cache it?
- return dbi.onDemand(CallContextSqlDao.class).getTenantRecordId(context.getTenantId().toString());
- }
- }
-
- private Long retrieveAccountRecordIdFromObject(final UUID objectId, final ObjectType objectType) {
- final Long accountRecordId;
-
- final TableName tableName = TableName.fromObjectType(objectType);
- if (tableName != null) {
- accountRecordId = dbi.withHandle(new HandleCallback<Long>() {
- @Override
- public Long withHandle(final Handle handle) throws Exception {
- final String columnName;
- if (TableName.TAG_DEFINITIONS.equals(tableName) || TableName.TAG_DEFINITION_HISTORY.equals(tableName)) {
- // Not tied to an account
- return null;
- } else if (TableName.ACCOUNT.equals(tableName) || TableName.ACCOUNT_HISTORY.equals(tableName)) {
- // Lookup the record_id directly
- columnName = "record_id";
- } else {
- // The table should have an account_record_id column
- columnName = "account_record_id";
- }
-
- final List<Map<String, Object>> values = handle.select(String.format("select %s from %s where id = ?;", columnName, tableName.getTableName()), objectId.toString());
- if (values.size() == 0) {
- return null;
- } else {
- final Object accountRecordId = values.get(0).get(columnName);
- return accountRecordId == null ? null : Long.valueOf(accountRecordId.toString());
- }
- }
- });
- } else {
- accountRecordId = null;
- }
- return accountRecordId;
- }
-
- private Long retrieveTenantRecordIdFromObject(final UUID objectId, final ObjectType objectType) {
- final Long tenantRecordId;
-
- final TableName tableName = TableName.fromObjectType(objectType);
- if (tableName != null) {
- tenantRecordId = dbi.withHandle(new HandleCallback<Long>() {
- @Override
- public Long withHandle(final Handle handle) throws Exception {
- final String columnName;
- if (TableName.TENANT.equals(tableName)) {
- // Lookup the record_id directly
- columnName = "record_id";
- } else {
- // The table should have an tenant_record_id column
- columnName = "tenant_record_id";
- }
-
- final List<Map<String, Object>> values = handle.select(String.format("select %s from %s where id = ?;", columnName, tableName.getTableName()), objectId.toString());
- if (values.size() == 0) {
- return null;
- } else {
- final Object tenantRecordId = values.get(0).get(columnName);
- return tenantRecordId == null ? null : Long.valueOf(tenantRecordId.toString());
- }
- }
- });
- } else {
- tenantRecordId = null;
+ return nonEntityDao.retrieveTenantRecordIdFromObject(context.getTenantId(), ObjectType.TENANT, cacheControllerDispatcher.getCacheController(CacheType.TENANT_RECORD_ID));
}
- return tenantRecordId;
}
}
diff --git a/util/src/main/java/com/ning/billing/util/customfield/dao/CustomFieldModelDao.java b/util/src/main/java/com/ning/billing/util/customfield/dao/CustomFieldModelDao.java
index 1f166d5..04b08f3 100644
--- a/util/src/main/java/com/ning/billing/util/customfield/dao/CustomFieldModelDao.java
+++ b/util/src/main/java/com/ning/billing/util/customfield/dao/CustomFieldModelDao.java
@@ -121,4 +121,10 @@ public class CustomFieldModelDao extends EntityBase implements EntityModelDao<Cu
public TableName getTableName() {
return TableName.CUSTOM_FIELD;
}
+
+ @Override
+ public TableName getHistoryTableName() {
+ return TableName.CUSTOM_FIELD_HISTORY;
+ }
+
}
diff --git a/util/src/main/java/com/ning/billing/util/customfield/dao/DefaultCustomFieldDao.java b/util/src/main/java/com/ning/billing/util/customfield/dao/DefaultCustomFieldDao.java
index 172229b..7f19fb0 100644
--- a/util/src/main/java/com/ning/billing/util/customfield/dao/DefaultCustomFieldDao.java
+++ b/util/src/main/java/com/ning/billing/util/customfield/dao/DefaultCustomFieldDao.java
@@ -24,9 +24,12 @@ import org.skife.jdbi.v2.IDBI;
import com.ning.billing.ErrorCode;
import com.ning.billing.ObjectType;
import com.ning.billing.util.api.CustomFieldApiException;
+import com.ning.billing.util.cache.CacheControllerDispatcher;
import com.ning.billing.util.callcontext.InternalCallContext;
import com.ning.billing.util.callcontext.InternalTenantContext;
+import com.ning.billing.util.clock.Clock;
import com.ning.billing.util.customfield.CustomField;
+import com.ning.billing.util.dao.NonEntityDao;
import com.ning.billing.util.entity.dao.EntityDaoBase;
import com.ning.billing.util.entity.dao.EntitySqlDao;
import com.ning.billing.util.entity.dao.EntitySqlDaoTransactionWrapper;
@@ -38,8 +41,8 @@ import com.google.inject.Inject;
public class DefaultCustomFieldDao extends EntityDaoBase<CustomFieldModelDao, CustomField, CustomFieldApiException> implements CustomFieldDao {
@Inject
- public DefaultCustomFieldDao(final IDBI dbi) {
- super(new EntitySqlDaoTransactionalJdbiWrapper(dbi), CustomFieldSqlDao.class);
+ public DefaultCustomFieldDao(final IDBI dbi, final Clock clock, final CacheControllerDispatcher controllerDispatcher, final NonEntityDao nonEntityDao) {
+ super(new EntitySqlDaoTransactionalJdbiWrapper(dbi, clock, controllerDispatcher, nonEntityDao), CustomFieldSqlDao.class);
}
@Override
diff --git a/util/src/main/java/com/ning/billing/util/dao/DefaultNonEntityDao.java b/util/src/main/java/com/ning/billing/util/dao/DefaultNonEntityDao.java
new file mode 100644
index 0000000..793ceef
--- /dev/null
+++ b/util/src/main/java/com/ning/billing/util/dao/DefaultNonEntityDao.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright 2010-2013 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.util.dao;
+
+import java.util.UUID;
+
+import javax.annotation.Nullable;
+import javax.inject.Inject;
+
+import org.skife.jdbi.v2.IDBI;
+
+import com.ning.billing.ObjectType;
+import com.ning.billing.util.cache.CacheController;
+
+public class DefaultNonEntityDao implements NonEntityDao {
+
+ private final NonEntitySqlDao nonEntitySqlDao;
+ private final WithCaching containedCall;
+
+
+ @Inject
+ public DefaultNonEntityDao(final IDBI dbi) {
+ this.nonEntitySqlDao = dbi.onDemand(NonEntitySqlDao.class);
+ this.containedCall = new WithCaching();
+ }
+
+
+ public Long retrieveRecordIdFromObject(final UUID objectId, final ObjectType objectType, @Nullable final CacheController<Object, Object> cache) {
+
+ return containedCall.withCaching(new OperationRetrieval<Long>() {
+ @Override
+ public Long doRetrieve(final UUID objectId, final ObjectType objectType) {
+ final TableName tableName = TableName.fromObjectType(objectType);
+ return nonEntitySqlDao.getRecordIdFromObject(objectId.toString(), tableName.getTableName());
+ }
+ }, objectId, objectType, cache);
+
+ }
+
+ public Long retrieveAccountRecordIdFromObject(final UUID objectId, final ObjectType objectType, @Nullable final CacheController<Object, Object> cache) {
+
+
+ return containedCall.withCaching(new OperationRetrieval<Long>() {
+ @Override
+ public Long doRetrieve(final UUID objectId, final ObjectType objectType) {
+ final TableName tableName = TableName.fromObjectType(objectType);
+ switch (tableName) {
+ case TENANT:
+ case TAG_DEFINITIONS:
+ case TAG_DEFINITION_HISTORY:
+ return null;
+
+ case ACCOUNT:
+ return nonEntitySqlDao.getAccountRecordIdFromAccount(objectId.toString());
+
+ default:
+ return nonEntitySqlDao.getAccountRecordIdFromObjectOtherThanAccount(objectId.toString(), tableName.getTableName());
+ }
+ }
+ }, objectId, objectType, cache);
+ }
+
+
+ public Long retrieveTenantRecordIdFromObject(final UUID objectId, final ObjectType objectType, @Nullable final CacheController<Object, Object> cache) {
+
+
+ return containedCall.withCaching(new OperationRetrieval<Long>() {
+ @Override
+ public Long doRetrieve(final UUID objectId, final ObjectType objectType) {
+ final TableName tableName = TableName.fromObjectType(objectType);
+ switch (tableName) {
+ case TENANT:
+ return nonEntitySqlDao.getTenantRecordIdFromTenant(objectId.toString());
+
+ default:
+ return nonEntitySqlDao.getTenantRecordIdFromObjectOtherThanTenant(objectId.toString(), tableName.getTableName());
+ }
+
+ }
+ }, objectId, objectType, cache);
+ }
+
+ @Override
+ public Long retrieveLastHistoryRecordIdFromTransaction(final Long targetRecordId, final TableName tableName, final NonEntitySqlDao transactional) {
+ // There is no caching here because the value returned changes as we add more history records, and so we would need some cache invalidation
+ return transactional.getLastHistoryRecordId(targetRecordId, tableName.getTableName());
+ }
+
+ @Override
+ public Long retrieveHistoryTargetRecordId(final Long recordId, final TableName tableName) {
+ return nonEntitySqlDao.getHistoryTargetRecordId(recordId, tableName.getTableName());
+ }
+
+
+ private interface OperationRetrieval<T> {
+ public T doRetrieve(final UUID objectId, final ObjectType objectType);
+ }
+
+
+ // 'cache' will be null for the CacheLoader classes -- or if cache is not configured.
+ private class WithCaching {
+ private Long withCaching(final OperationRetrieval<Long> op, final UUID objectId, final ObjectType objectType, @Nullable final CacheController<Object, Object> cache) {
+ if (cache != null) {
+ final Long cachedResult = (Long) cache.get(objectId.toString(), objectType);
+ return cachedResult;
+ }
+ return op.doRetrieve(objectId, objectType);
+ }
+ }
+}
diff --git a/util/src/main/java/com/ning/billing/util/dao/NonEntityDao.java b/util/src/main/java/com/ning/billing/util/dao/NonEntityDao.java
new file mode 100644
index 0000000..26be4a4
--- /dev/null
+++ b/util/src/main/java/com/ning/billing/util/dao/NonEntityDao.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2010-2013 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.util.dao;
+
+import java.util.UUID;
+
+import javax.annotation.Nullable;
+
+import com.ning.billing.ObjectType;
+import com.ning.billing.util.cache.CacheController;
+import com.ning.billing.util.entity.dao.EntitySqlDaoWrapperFactory;
+
+public interface NonEntityDao {
+
+ //
+ // TODO should we check for InternalCallContext?
+ // That seems difficult because those APIs are called when creating a context or from the cache loaders which also dpn't know anything about context
+ //
+ public Long retrieveRecordIdFromObject(final UUID objectId, final ObjectType objectType, @Nullable final CacheController<Object, Object> cache);
+
+ public Long retrieveAccountRecordIdFromObject(final UUID objectId, final ObjectType objectType, @Nullable final CacheController<Object, Object> cache);
+
+ public Long retrieveTenantRecordIdFromObject(final UUID objectId, final ObjectType objectType, @Nullable final CacheController<Object, Object> cache);
+
+ // This retrieves from the history table the latest record for which targetId matches the one we are passing
+ public Long retrieveLastHistoryRecordIdFromTransaction(final Long targetRecordId, final TableName tableName, final NonEntitySqlDao transactional);
+
+ //This is the reverse from retrieveLastHistoryRecordIdFromTransaction; this retrieves the record_id of the object matching a given history row
+ public Long retrieveHistoryTargetRecordId(final Long recordId, final TableName tableName);
+}
diff --git a/util/src/main/java/com/ning/billing/util/dao/NonEntitySqlDao.java b/util/src/main/java/com/ning/billing/util/dao/NonEntitySqlDao.java
new file mode 100644
index 0000000..f0a119d
--- /dev/null
+++ b/util/src/main/java/com/ning/billing/util/dao/NonEntitySqlDao.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2010-2013 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.util.dao;
+
+import org.skife.jdbi.v2.sqlobject.Bind;
+import org.skife.jdbi.v2.sqlobject.SqlQuery;
+import org.skife.jdbi.v2.sqlobject.customizers.Define;
+import org.skife.jdbi.v2.sqlobject.mixins.CloseMe;
+import org.skife.jdbi.v2.sqlobject.mixins.Transactional;
+import org.skife.jdbi.v2.sqlobject.stringtemplate.UseStringTemplate3StatementLocator;
+
+@UseStringTemplate3StatementLocator
+public interface NonEntitySqlDao extends Transactional<NonEntitySqlDao>, CloseMe {
+
+ @SqlQuery
+ public Long getRecordIdFromObject(@Bind("id") String id, @Define("tableName") final String tableName);
+
+ @SqlQuery
+ public Long getAccountRecordIdFromAccount(@Bind("id") String id);
+
+ @SqlQuery
+ public Long getAccountRecordIdFromAccountHistory(@Bind("id") String id);
+
+ @SqlQuery
+ public Long getAccountRecordIdFromObjectOtherThanAccount(@Bind("id") String id, @Define("tableName") final String tableName);
+
+ @SqlQuery
+ public Long getTenantRecordIdFromTenant(@Bind("id") String id);
+
+ @SqlQuery
+ public Long getTenantRecordIdFromObjectOtherThanTenant(@Bind("id") String id, @Define("tableName") final String tableName);
+
+ @SqlQuery
+ public Long getLastHistoryRecordId(@Bind("targetRecordId") Long targetRecordId, @Define("tableName") final String tableName);
+
+ @SqlQuery
+ public Long getHistoryTargetRecordId(@Bind("recordId") Long recordId, @Define("tableName") final String tableName);
+}
diff --git a/util/src/main/java/com/ning/billing/util/entity/dao/EntityModelDao.java b/util/src/main/java/com/ning/billing/util/entity/dao/EntityModelDao.java
index 5e0e02f..d822a32 100644
--- a/util/src/main/java/com/ning/billing/util/entity/dao/EntityModelDao.java
+++ b/util/src/main/java/com/ning/billing/util/entity/dao/EntityModelDao.java
@@ -35,4 +35,7 @@ public interface EntityModelDao<E extends Entity> extends Entity {
* @return the TableName object associated with this ModelDao entity
*/
public TableName getTableName();
+
+
+ public TableName getHistoryTableName();
}
diff --git a/util/src/main/java/com/ning/billing/util/entity/dao/EntitySqlDao.java b/util/src/main/java/com/ning/billing/util/entity/dao/EntitySqlDao.java
index 58243d3..418dbee 100644
--- a/util/src/main/java/com/ning/billing/util/entity/dao/EntitySqlDao.java
+++ b/util/src/main/java/com/ning/billing/util/entity/dao/EntitySqlDao.java
@@ -27,6 +27,8 @@ import org.skife.jdbi.v2.sqlobject.mixins.Transactional;
import org.skife.jdbi.v2.sqlobject.mixins.Transmogrifier;
import com.ning.billing.util.audit.ChangeType;
+import com.ning.billing.util.cache.Cachable;
+import com.ning.billing.util.cache.Cachable.CacheType;
import com.ning.billing.util.callcontext.InternalCallContext;
import com.ning.billing.util.callcontext.InternalTenantContext;
import com.ning.billing.util.dao.AuditSqlDao;
@@ -54,19 +56,10 @@ public interface EntitySqlDao<M extends EntityModelDao<E>, E extends Entity> ext
@BindBean final InternalTenantContext context);
@SqlQuery
+ @Cachable(CacheType.RECORD_ID)
public Long getRecordId(@Bind("id") final String id,
@BindBean final InternalTenantContext context);
- // Given entity recordId find the history recordId (targetRecordId for history table = entity recordId)
- @SqlQuery
- public Long getHistoryRecordId(@Bind("targetRecordId") final Long targetRecordId,
- @BindBean final InternalTenantContext context);
-
- // Given history recordId find the entity recordId (targetRecordId for history table = entity recordId)
- @SqlQuery
- public Long getHistoryTargetRecordId(@Bind("recordId") final Long recordId,
- @BindBean final InternalTenantContext context);
-
@SqlQuery
public List<M> get(@BindBean final InternalTenantContext context);
diff --git a/util/src/main/java/com/ning/billing/util/entity/dao/EntitySqlDaoTransactionalJdbiWrapper.java b/util/src/main/java/com/ning/billing/util/entity/dao/EntitySqlDaoTransactionalJdbiWrapper.java
index 13ba96c..35098ca 100644
--- a/util/src/main/java/com/ning/billing/util/entity/dao/EntitySqlDaoTransactionalJdbiWrapper.java
+++ b/util/src/main/java/com/ning/billing/util/entity/dao/EntitySqlDaoTransactionalJdbiWrapper.java
@@ -20,6 +20,9 @@ import org.skife.jdbi.v2.IDBI;
import org.skife.jdbi.v2.Transaction;
import org.skife.jdbi.v2.TransactionStatus;
+import com.ning.billing.util.cache.CacheControllerDispatcher;
+import com.ning.billing.util.clock.Clock;
+import com.ning.billing.util.dao.NonEntityDao;
import com.ning.billing.util.entity.Entity;
/**
@@ -28,9 +31,15 @@ import com.ning.billing.util.entity.Entity;
public class EntitySqlDaoTransactionalJdbiWrapper {
private final IDBI dbi;
+ private final Clock clock;
+ private final CacheControllerDispatcher cacheControllerDispatcher;
+ private final NonEntityDao nonEntityDao;
- public EntitySqlDaoTransactionalJdbiWrapper(final IDBI dbi) {
+ public EntitySqlDaoTransactionalJdbiWrapper(final IDBI dbi, final Clock clock, final CacheControllerDispatcher cacheControllerDispatcher, final NonEntityDao nonEntityDao) {
this.dbi = dbi;
+ this.clock = clock;
+ this.cacheControllerDispatcher = cacheControllerDispatcher;
+ this.nonEntityDao = nonEntityDao;
}
class JdbiTransaction<ReturnType, M extends EntityModelDao<E>, E extends Entity> implements Transaction<ReturnType, EntitySqlDao<M, E>> {
@@ -43,7 +52,7 @@ public class EntitySqlDaoTransactionalJdbiWrapper {
@Override
public ReturnType inTransaction(final EntitySqlDao<M, E> transactionalSqlDao, final TransactionStatus status) throws Exception {
- final EntitySqlDaoWrapperFactory<EntitySqlDao> factoryEntitySqlDao = new EntitySqlDaoWrapperFactory<EntitySqlDao>(transactionalSqlDao);
+ final EntitySqlDaoWrapperFactory<EntitySqlDao> factoryEntitySqlDao = new EntitySqlDaoWrapperFactory<EntitySqlDao>(transactionalSqlDao, clock, cacheControllerDispatcher, nonEntityDao);
return entitySqlDaoTransactionWrapper.inTransaction(factoryEntitySqlDao);
}
}
diff --git a/util/src/main/java/com/ning/billing/util/entity/dao/EntitySqlDaoWrapperFactory.java b/util/src/main/java/com/ning/billing/util/entity/dao/EntitySqlDaoWrapperFactory.java
index b9dd2d4..08d5a35 100644
--- a/util/src/main/java/com/ning/billing/util/entity/dao/EntitySqlDaoWrapperFactory.java
+++ b/util/src/main/java/com/ning/billing/util/entity/dao/EntitySqlDaoWrapperFactory.java
@@ -18,6 +18,9 @@ package com.ning.billing.util.entity.dao;
import java.lang.reflect.Proxy;
+import com.ning.billing.util.cache.CacheControllerDispatcher;
+import com.ning.billing.util.clock.Clock;
+import com.ning.billing.util.dao.NonEntityDao;
import com.ning.billing.util.entity.Entity;
/**
@@ -30,9 +33,16 @@ import com.ning.billing.util.entity.Entity;
public class EntitySqlDaoWrapperFactory<InitialSqlDao extends EntitySqlDao> {
private final InitialSqlDao sqlDao;
+ private final Clock clock;
+ private final CacheControllerDispatcher cacheControllerDispatcher;
- public EntitySqlDaoWrapperFactory(final InitialSqlDao sqlDao) {
+ private final NonEntityDao nonEntityDao;
+
+ public EntitySqlDaoWrapperFactory(final InitialSqlDao sqlDao, final Clock clock, final CacheControllerDispatcher cacheControllerDispatcher, final NonEntityDao nonEntityDao) {
this.sqlDao = sqlDao;
+ this.clock = clock;
+ this.cacheControllerDispatcher = cacheControllerDispatcher;
+ this.nonEntityDao = nonEntityDao;
}
/**
@@ -59,7 +69,7 @@ public class EntitySqlDaoWrapperFactory<InitialSqlDao extends EntitySqlDao> {
final ClassLoader classLoader = newSqlDao.getClass().getClassLoader();
final Class[] interfacesToImplement = {newSqlDaoClass};
final EntitySqlDaoWrapperInvocationHandler<NewSqlDao, NewEntityModelDao, NewEntity> wrapperInvocationHandler =
- new EntitySqlDaoWrapperInvocationHandler<NewSqlDao, NewEntityModelDao, NewEntity>(newSqlDaoClass, newSqlDao);
+ new EntitySqlDaoWrapperInvocationHandler<NewSqlDao, NewEntityModelDao, NewEntity>(newSqlDaoClass, newSqlDao, clock, cacheControllerDispatcher, nonEntityDao);
final Object newSqlDaoObject = Proxy.newProxyInstance(classLoader, interfacesToImplement, wrapperInvocationHandler);
return newSqlDaoClass.cast(newSqlDaoObject);
diff --git a/util/src/main/java/com/ning/billing/util/entity/dao/EntitySqlDaoWrapperInvocationHandler.java b/util/src/main/java/com/ning/billing/util/entity/dao/EntitySqlDaoWrapperInvocationHandler.java
index 1ded618..0cd07c6 100644
--- a/util/src/main/java/com/ning/billing/util/entity/dao/EntitySqlDaoWrapperInvocationHandler.java
+++ b/util/src/main/java/com/ning/billing/util/entity/dao/EntitySqlDaoWrapperInvocationHandler.java
@@ -18,13 +18,16 @@ package com.ning.billing.util.entity.dao;
import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
+import java.lang.reflect.Type;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import java.util.UUID;
import org.skife.jdbi.v2.Binding;
import org.skife.jdbi.v2.StatementContext;
@@ -34,12 +37,21 @@ import org.skife.jdbi.v2.sqlobject.Bind;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import com.ning.billing.ObjectType;
import com.ning.billing.util.audit.ChangeType;
+import com.ning.billing.util.cache.Cachable;
+import com.ning.billing.util.cache.Cachable.CacheType;
+import com.ning.billing.util.cache.CacheController;
+import com.ning.billing.util.cache.CacheControllerDispatcher;
import com.ning.billing.util.callcontext.InternalCallContext;
+import com.ning.billing.util.clock.Clock;
import com.ning.billing.util.dao.EntityAudit;
import com.ning.billing.util.dao.EntityHistoryModelDao;
+import com.ning.billing.util.dao.NonEntityDao;
+import com.ning.billing.util.dao.NonEntitySqlDao;
import com.ning.billing.util.dao.TableName;
import com.ning.billing.util.entity.Entity;
+import com.ning.billing.util.tag.dao.TagSqlDao;
import com.google.common.base.Objects;
import com.google.common.collect.ImmutableList;
@@ -59,9 +71,16 @@ public class EntitySqlDaoWrapperInvocationHandler<S extends EntitySqlDao<M, E>,
private final Class<S> sqlDaoClass;
private final S sqlDao;
- public EntitySqlDaoWrapperInvocationHandler(final Class<S> sqlDaoClass, final S sqlDao) {
+ private final CacheControllerDispatcher cacheControllerDispatcher;
+ private final Clock clock;
+ private final NonEntityDao nonEntityDao;
+
+ public EntitySqlDaoWrapperInvocationHandler(final Class<S> sqlDaoClass, final S sqlDao, final Clock clock, final CacheControllerDispatcher cacheControllerDispatcher, final NonEntityDao nonEntityDao) {
this.sqlDaoClass = sqlDaoClass;
this.sqlDao = sqlDao;
+ this.clock = clock;
+ this.cacheControllerDispatcher = cacheControllerDispatcher;
+ this.nonEntityDao = nonEntityDao;
}
@Override
@@ -134,13 +153,87 @@ public class EntitySqlDaoWrapperInvocationHandler<S extends EntitySqlDao<M, E>,
}
private Object invokeSafely(final Object proxy, final Method method, final Object[] args) throws Throwable {
- final Audited annotation = method.getAnnotation(Audited.class);
+ final Audited auditedAnnotation = method.getAnnotation(Audited.class);
+ final Cachable cachableAnnotation = method.getAnnotation(Cachable.class);
+
+ // This can't be AUDIT'ed and CACHABLE'd at the same time as we only cache 'get'
+ if (auditedAnnotation != null) {
+ return invokeWithAuditAndHistory(auditedAnnotation, method, args);
+ } else if (cachableAnnotation != null) {
+ return invokeWithCaching(cachableAnnotation, method, args);
+ } else {
+ return method.invoke(sqlDao, args);
+ }
+ }
+
+ private Object invokeWithCaching(final Cachable cachableAnnotation, final Method method, final Object[] args)
+ throws IllegalAccessException, InvocationTargetException, ClassNotFoundException, InstantiationException {
+
+ final ObjectType objectType = getObjectType();
+ final CacheType cacheType = cachableAnnotation.value();
+ final CacheController<Object, Object> cache = cacheControllerDispatcher.getCacheController(cacheType);
+ Object result = null;
+ if (cache != null) {
+ // STEPH : Assume first argument is the key for the cache, this is a bit fragile...
+ result = cache.get(args[0], objectType);
+ }
+ if (result == null) {
+ result = method.invoke(sqlDao, args);
+ }
+ return result;
+ }
+
+ /**
+ * Extract object from sqlDaoClass by looking at first parameter type (EntityModelDao) and
+ * constructing an empty object so we can call the getObjectType method on it.
+ *
+ * @return the objectType associated to that handler
+ * @throws InstantiationException
+ * @throws IllegalAccessException
+ * @throws ClassNotFoundException
+ */
+ private ObjectType getObjectType() throws InstantiationException, IllegalAccessException, ClassNotFoundException {
+
+ int foundIndexForEntitySqlDao = -1;
+ // If the sqlDaoClass implements multiple interfaces, first figure out which one is the EntitySqlDao
+ for (int i = 0; i < sqlDaoClass.getGenericInterfaces().length; i++) {
+ if (EntitySqlDao.class.getName().equals(((Class) ((java.lang.reflect.ParameterizedType) sqlDaoClass.getGenericInterfaces()[0]).getRawType()).getName())) {
+ foundIndexForEntitySqlDao = i;
+ break;
+ }
+ }
+ // Find out from the parameters of the EntitySqlDao which one is the EntityModelDao, and extract his (sub)type to finally return the ObjectType
+ if (foundIndexForEntitySqlDao >= 0) {
+ Type[] types = ((java.lang.reflect.ParameterizedType) sqlDaoClass.getGenericInterfaces()[foundIndexForEntitySqlDao]).getActualTypeArguments();
+ int foundIndexForEntityModelDao = -1;
+ for (int i = 0; i < types.length; i++) {
+ Class clz = ((Class) types[i]);
+ if (EntityModelDao.class.getName().equals(((Class) ((java.lang.reflect.ParameterizedType) clz.getGenericInterfaces()[0]).getRawType()).getName())) {
+ foundIndexForEntityModelDao = i;
+ break;
+ }
+ }
+
+ if (foundIndexForEntityModelDao >= 0) {
+ String modelClassName = ((Class) types[foundIndexForEntityModelDao]).getName();
+
+ Class<? extends EntityModelDao<?>> clz = (Class<? extends EntityModelDao<?>>) Class.forName(modelClassName);
+
+ EntityModelDao<?> modelDao = (EntityModelDao<?>) clz.newInstance();
+ return modelDao.getTableName().getObjectType();
+ }
+ }
+ return null;
+ }
+
+
+ private Object invokeWithAuditAndHistory(final Audited auditedAnnotation, final Method method, final Object[] args) throws IllegalAccessException, InvocationTargetException {
InternalCallContext context = null;
List<String> entityIds = null;
final Map<String, M> entities = new HashMap<String, M>();
final Map<String, Long> entityRecordIds = new HashMap<String, Long>();
- if (annotation != null) {
+ if (auditedAnnotation != null) {
// There will be some work required after the statement is executed,
// get the id before in case the change is a delete
context = retrieveContextFromArguments(args);
@@ -154,15 +247,11 @@ public class EntitySqlDaoWrapperInvocationHandler<S extends EntitySqlDao<M, E>,
// Real jdbc call
final Object obj = method.invoke(sqlDao, args);
- // Update audit and history if needed
- if (annotation != null) {
- final ChangeType changeType = annotation.value();
+ final ChangeType changeType = auditedAnnotation.value();
- for (final String entityId : entityIds) {
- updateHistoryAndAudit(entityId, entities, entityRecordIds, changeType, context);
- }
+ for (final String entityId : entityIds) {
+ updateHistoryAndAudit(entityId, entities, entityRecordIds, changeType, context);
}
-
return obj;
}
@@ -250,16 +339,19 @@ public class EntitySqlDaoWrapperInvocationHandler<S extends EntitySqlDao<M, E>,
}
private Long insertHistory(final Long entityRecordId, final M entityModelDao, final ChangeType changeType, final InternalCallContext context) {
- // TODO use clock
- final EntityHistoryModelDao<M, E> history = new EntityHistoryModelDao<M, E>(entityModelDao, entityRecordId, changeType, context.getCreatedDate());
+ final EntityHistoryModelDao<M, E> history = new EntityHistoryModelDao<M, E>(entityModelDao, entityRecordId, changeType, clock.getUTCNow());
+
sqlDao.addHistoryFromTransaction(history, context);
- return sqlDao.getHistoryRecordId(entityRecordId, context);
+
+ final NonEntitySqlDao transactional = sqlDao.become(NonEntitySqlDao.class);
+
+ /* return transactional.getLastHistoryRecordId(entityRecordId, entityModelDao.getHistoryTableName().getTableName()); */
+ return nonEntityDao.retrieveLastHistoryRecordIdFromTransaction(entityRecordId, entityModelDao.getHistoryTableName(), transactional);
}
private void insertAudits(final TableName tableName, final Long historyRecordId, final ChangeType changeType, final InternalCallContext context) {
- // TODO use clock
final TableName destinationTableName = Objects.firstNonNull(tableName.getHistoryTableName(), tableName);
- final EntityAudit audit = new EntityAudit(destinationTableName, historyRecordId, changeType, context.getCreatedDate());
+ final EntityAudit audit = new EntityAudit(destinationTableName, historyRecordId, changeType, clock.getUTCNow());
sqlDao.insertAuditFromTransaction(audit, context);
}
}
diff --git a/util/src/main/java/com/ning/billing/util/glue/CacheModule.java b/util/src/main/java/com/ning/billing/util/glue/CacheModule.java
new file mode 100644
index 0000000..a304b3c
--- /dev/null
+++ b/util/src/main/java/com/ning/billing/util/glue/CacheModule.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2010-2013 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.util.glue;
+
+import java.util.UUID;
+
+import org.skife.config.ConfigSource;
+import org.skife.config.ConfigurationObjectFactory;
+import org.skife.config.SimplePropertyConfigSource;
+
+import com.ning.billing.util.cache.AccountRecordIdCacheLoader;
+import com.ning.billing.util.cache.Cachable;
+import com.ning.billing.util.cache.Cachable.CacheType;
+import com.ning.billing.util.cache.CacheController;
+import com.ning.billing.util.cache.CacheControllerDispatcher;
+import com.ning.billing.util.cache.CacheControllerProvider;
+import com.ning.billing.util.cache.CacheManagerProvider;
+import com.ning.billing.util.cache.RecordIdCacheLoader;
+import com.ning.billing.util.cache.TenantRecordIdCacheLoader;
+import com.ning.billing.util.config.CacheConfig;
+
+import com.google.inject.AbstractModule;
+import com.google.inject.Singleton;
+import com.google.inject.TypeLiteral;
+import com.google.inject.name.Named;
+import com.google.inject.name.Names;
+import net.sf.ehcache.CacheManager;
+import net.sf.ehcache.loader.CacheLoader;
+
+public class CacheModule extends AbstractModule {
+
+
+ public static final Named RECORD_ID_CACHE_NAMED = Names.named(Cachable.RECORD_ID_CACHE_NAME);
+ public static final Named ACCOUNT_RECORD_ID_CACHE_NAMED = Names.named(Cachable.ACCOUNT_RECORD_ID_CACHE_NAME);
+ public static final Named TENANT_RECORD_ID_CACHE_NAMED = Names.named(Cachable.TENANT_RECORD_ID_CACHE_NAME);
+
+ protected void installConfig() {
+ final ConfigSource configSource = new SimplePropertyConfigSource(System.getProperties());
+ final CacheConfig config = new ConfigurationObjectFactory(configSource).build(CacheConfig.class);
+ bind(CacheConfig.class).toInstance(config);
+ }
+
+ @Override
+ protected void configure() {
+
+ installConfig();
+
+ bind(CacheManager.class).toProvider(CacheManagerProvider.class).asEagerSingleton();
+
+ bind(CacheLoader.class).annotatedWith(RECORD_ID_CACHE_NAMED).to(RecordIdCacheLoader.class).asEagerSingleton();
+ bind(new TypeLiteral<CacheController<UUID, Long>>() {}).annotatedWith(RECORD_ID_CACHE_NAMED).toProvider(new CacheControllerProvider<UUID, Long>(Cachable.RECORD_ID_CACHE_NAME)).asEagerSingleton();
+
+ bind(CacheLoader.class).annotatedWith(ACCOUNT_RECORD_ID_CACHE_NAMED).to(AccountRecordIdCacheLoader.class).asEagerSingleton();
+ bind(new TypeLiteral<CacheController<UUID, Long>>() {}).annotatedWith(ACCOUNT_RECORD_ID_CACHE_NAMED).toProvider(new CacheControllerProvider<UUID, Long>(Cachable.ACCOUNT_RECORD_ID_CACHE_NAME)).asEagerSingleton();
+
+ bind(CacheLoader.class).annotatedWith(TENANT_RECORD_ID_CACHE_NAMED).to(TenantRecordIdCacheLoader.class).asEagerSingleton();
+ bind(new TypeLiteral<CacheController<UUID, Long>>() {}).annotatedWith(TENANT_RECORD_ID_CACHE_NAMED).toProvider(new CacheControllerProvider<UUID, Long>(Cachable.TENANT_RECORD_ID_CACHE_NAME)).asEagerSingleton();
+
+ bind(CacheControllerDispatcher.class).asEagerSingleton();
+ }
+}
diff --git a/util/src/main/java/com/ning/billing/util/glue/CallContextModule.java b/util/src/main/java/com/ning/billing/util/glue/CallContextModule.java
index a287c37..5a0b43e 100644
--- a/util/src/main/java/com/ning/billing/util/glue/CallContextModule.java
+++ b/util/src/main/java/com/ning/billing/util/glue/CallContextModule.java
@@ -18,6 +18,7 @@ package com.ning.billing.util.glue;
import com.ning.billing.util.callcontext.CallContextFactory;
import com.ning.billing.util.callcontext.DefaultCallContextFactory;
+import com.ning.billing.util.callcontext.InternalCallContextFactory;
import com.google.inject.AbstractModule;
@@ -25,5 +26,6 @@ public class CallContextModule extends AbstractModule {
@Override
protected void configure() {
bind(CallContextFactory.class).to(DefaultCallContextFactory.class).asEagerSingleton();
+ bind(InternalCallContextFactory.class).asEagerSingleton();
}
}
diff --git a/util/src/main/java/com/ning/billing/util/notificationq/DefaultNotificationQueue.java b/util/src/main/java/com/ning/billing/util/notificationq/DefaultNotificationQueue.java
index 59379fc..208a211 100644
--- a/util/src/main/java/com/ning/billing/util/notificationq/DefaultNotificationQueue.java
+++ b/util/src/main/java/com/ning/billing/util/notificationq/DefaultNotificationQueue.java
@@ -28,9 +28,13 @@ import org.skife.jdbi.v2.tweak.HandleCallback;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import com.ning.billing.ObjectType;
import com.ning.billing.util.Hostname;
+import com.ning.billing.util.cache.Cachable.CacheType;
+import com.ning.billing.util.cache.CacheControllerDispatcher;
import com.ning.billing.util.callcontext.InternalCallContext;
+import com.ning.billing.util.dao.NonEntityDao;
import com.ning.billing.util.entity.dao.EntitySqlDao;
import com.ning.billing.util.entity.dao.EntitySqlDaoWrapperFactory;
import com.ning.billing.util.notificationq.NotificationQueueService.NotificationQueueHandler;
@@ -55,15 +59,21 @@ public class DefaultNotificationQueue implements NotificationQueue {
private final NotificationQueueHandler handler;
private final NotificationQueueService notificationQueueService;
+ private final NonEntityDao nonEntityDao;
+ private final CacheControllerDispatcher cacheControllerDispatcher;
+
private volatile boolean isStarted;
public DefaultNotificationQueue(final String svcName, final String queueName, final NotificationQueueHandler handler,
- final IDBI dbi, final NotificationQueueService notificationQueueService) {
+ final IDBI dbi, final NotificationQueueService notificationQueueService,
+ final NonEntityDao nonEntityDao, final CacheControllerDispatcher cacheControllerDispatcher) {
this.svcName = svcName;
this.queueName = queueName;
this.handler = handler;
this.dbi = dbi;
+ this.nonEntityDao = nonEntityDao;
+ this.cacheControllerDispatcher = cacheControllerDispatcher;
this.dao = dbi.onDemand(NotificationSqlDao.class);
this.hostname = Hostname.get();
this.notificationQueueService = notificationQueueService;
@@ -108,19 +118,7 @@ public class DefaultNotificationQueue implements NotificationQueue {
@Override
public List<Notification> getNotificationForAccountAndDate(final UUID accountId, final DateTime effectiveDate, final InternalCallContext context) {
- // TODO we have the same use case in InternalCallContextFactory, do we need some sort of helper class?
- final Long accountRecordId = dbi.withHandle(new HandleCallback<Long>() {
- @Override
- public Long withHandle(final Handle handle) throws Exception {
- final List<Map<String, Object>> values = handle.select("select record_id from accounts where id = " + accountId.toString());
- if (values.size() == 0) {
- return null;
- } else {
- return (Long) values.get(0).get("record_id");
- }
- }
- });
-
+ final Long accountRecordId = nonEntityDao.retrieveRecordIdFromObject(accountId, ObjectType.ACCOUNT, cacheControllerDispatcher.getCacheController(CacheType.RECORD_ID));
if (accountId == null) {
return ImmutableList.<Notification>of();
} else {
diff --git a/util/src/main/java/com/ning/billing/util/notificationq/DefaultNotificationQueueService.java b/util/src/main/java/com/ning/billing/util/notificationq/DefaultNotificationQueueService.java
index dcb7e0b..d1a31db 100644
--- a/util/src/main/java/com/ning/billing/util/notificationq/DefaultNotificationQueueService.java
+++ b/util/src/main/java/com/ning/billing/util/notificationq/DefaultNotificationQueueService.java
@@ -18,20 +18,27 @@ package com.ning.billing.util.notificationq;
import org.skife.jdbi.v2.IDBI;
+import com.ning.billing.util.cache.CacheControllerDispatcher;
import com.ning.billing.util.callcontext.InternalCallContextFactory;
import com.ning.billing.util.clock.Clock;
+import com.ning.billing.util.dao.NonEntityDao;
import com.google.inject.Inject;
public class DefaultNotificationQueueService extends NotificationQueueServiceBase {
private final IDBI dbi;
+ private final NonEntityDao nonEntityDao;
+ private final CacheControllerDispatcher cacheControllerDispatcher;
+
@Inject
public DefaultNotificationQueueService(final IDBI dbi, final Clock clock, final NotificationQueueConfig config,
- final InternalCallContextFactory internalCallContextFactory) {
+ final InternalCallContextFactory internalCallContextFactory, final NonEntityDao nonEntityDao, final CacheControllerDispatcher cacheControllerDispatcher) {
super(clock, config, dbi, internalCallContextFactory);
this.dbi = dbi;
+ this.nonEntityDao = nonEntityDao;
+ this.cacheControllerDispatcher = cacheControllerDispatcher;
}
@@ -39,6 +46,6 @@ public class DefaultNotificationQueueService extends NotificationQueueServiceBas
protected NotificationQueue createNotificationQueueInternal(final String svcName,
final String queueName,
final NotificationQueueHandler handler) {
- return new DefaultNotificationQueue(svcName, queueName, handler, dbi, this);
+ return new DefaultNotificationQueue(svcName, queueName, handler, dbi, this, nonEntityDao, cacheControllerDispatcher);
}
}
diff --git a/util/src/main/java/com/ning/billing/util/tag/dao/DefaultTagDao.java b/util/src/main/java/com/ning/billing/util/tag/dao/DefaultTagDao.java
index d40fbf4..cd5a164 100644
--- a/util/src/main/java/com/ning/billing/util/tag/dao/DefaultTagDao.java
+++ b/util/src/main/java/com/ning/billing/util/tag/dao/DefaultTagDao.java
@@ -28,8 +28,11 @@ import com.ning.billing.ErrorCode;
import com.ning.billing.ObjectType;
import com.ning.billing.util.api.TagApiException;
import com.ning.billing.util.audit.ChangeType;
+import com.ning.billing.util.cache.CacheControllerDispatcher;
import com.ning.billing.util.callcontext.InternalCallContext;
import com.ning.billing.util.callcontext.InternalTenantContext;
+import com.ning.billing.util.clock.Clock;
+import com.ning.billing.util.dao.NonEntityDao;
import com.ning.billing.util.entity.dao.EntityDaoBase;
import com.ning.billing.util.entity.dao.EntitySqlDao;
import com.ning.billing.util.entity.dao.EntitySqlDaoTransactionWrapper;
@@ -51,8 +54,9 @@ public class DefaultTagDao extends EntityDaoBase<TagModelDao, Tag, TagApiExcepti
private final InternalBus bus;
@Inject
- public DefaultTagDao(final IDBI dbi, final TagEventBuilder tagEventBuilder, final InternalBus bus) {
- super(new EntitySqlDaoTransactionalJdbiWrapper(dbi), TagSqlDao.class);
+ public DefaultTagDao(final IDBI dbi, final TagEventBuilder tagEventBuilder, final InternalBus bus, final Clock clock,
+ final CacheControllerDispatcher controllerDispatcher, final NonEntityDao nonEntityDao) {
+ super(new EntitySqlDaoTransactionalJdbiWrapper(dbi, clock, controllerDispatcher, nonEntityDao), TagSqlDao.class);
this.tagEventBuilder = tagEventBuilder;
this.bus = bus;
}
diff --git a/util/src/main/java/com/ning/billing/util/tag/dao/DefaultTagDefinitionDao.java b/util/src/main/java/com/ning/billing/util/tag/dao/DefaultTagDefinitionDao.java
index 968c957..8b8b2fd 100644
--- a/util/src/main/java/com/ning/billing/util/tag/dao/DefaultTagDefinitionDao.java
+++ b/util/src/main/java/com/ning/billing/util/tag/dao/DefaultTagDefinitionDao.java
@@ -30,8 +30,11 @@ import com.ning.billing.BillingExceptionBase;
import com.ning.billing.ErrorCode;
import com.ning.billing.util.api.TagDefinitionApiException;
import com.ning.billing.util.audit.ChangeType;
+import com.ning.billing.util.cache.CacheControllerDispatcher;
import com.ning.billing.util.callcontext.InternalCallContext;
import com.ning.billing.util.callcontext.InternalTenantContext;
+import com.ning.billing.util.clock.Clock;
+import com.ning.billing.util.dao.NonEntityDao;
import com.ning.billing.util.entity.dao.EntityDaoBase;
import com.ning.billing.util.entity.dao.EntitySqlDao;
import com.ning.billing.util.entity.dao.EntitySqlDaoTransactionWrapper;
@@ -55,8 +58,9 @@ public class DefaultTagDefinitionDao extends EntityDaoBase<TagDefinitionModelDao
private final InternalBus bus;
@Inject
- public DefaultTagDefinitionDao(final IDBI dbi, final TagEventBuilder tagEventBuilder, final InternalBus bus) {
- super(new EntitySqlDaoTransactionalJdbiWrapper(dbi), TagDefinitionSqlDao.class);
+ public DefaultTagDefinitionDao(final IDBI dbi, final TagEventBuilder tagEventBuilder, final InternalBus bus, final Clock clock,
+ final CacheControllerDispatcher controllerDispatcher, final NonEntityDao nonEntityDao) {
+ super(new EntitySqlDaoTransactionalJdbiWrapper(dbi, clock, controllerDispatcher, nonEntityDao), TagDefinitionSqlDao.class);
this.tagEventBuilder = tagEventBuilder;
this.bus = bus;
}
diff --git a/util/src/main/java/com/ning/billing/util/tag/dao/TagDefinitionModelDao.java b/util/src/main/java/com/ning/billing/util/tag/dao/TagDefinitionModelDao.java
index 5c0aaf9..10acfb9 100644
--- a/util/src/main/java/com/ning/billing/util/tag/dao/TagDefinitionModelDao.java
+++ b/util/src/main/java/com/ning/billing/util/tag/dao/TagDefinitionModelDao.java
@@ -117,4 +117,10 @@ public class TagDefinitionModelDao extends EntityBase implements EntityModelDao<
public TableName getTableName() {
return TableName.TAG_DEFINITIONS;
}
+
+ @Override
+ public TableName getHistoryTableName() {
+ return TableName.TAG_DEFINITION_HISTORY;
+ }
+
}
diff --git a/util/src/main/java/com/ning/billing/util/tag/dao/TagModelDao.java b/util/src/main/java/com/ning/billing/util/tag/dao/TagModelDao.java
index 8d381df..ea6ce3f 100644
--- a/util/src/main/java/com/ning/billing/util/tag/dao/TagModelDao.java
+++ b/util/src/main/java/com/ning/billing/util/tag/dao/TagModelDao.java
@@ -125,4 +125,10 @@ public class TagModelDao extends EntityBase implements EntityModelDao<Tag> {
public TableName getTableName() {
return TableName.TAG;
}
+
+ @Override
+ public TableName getHistoryTableName() {
+ return TableName.TAG_HISTORY;
+ }
+
}
diff --git a/util/src/main/resources/com/ning/billing/util/dao/NonEntitySqlDao.sql.stg b/util/src/main/resources/com/ning/billing/util/dao/NonEntitySqlDao.sql.stg
new file mode 100644
index 0000000..3e11edb
--- /dev/null
+++ b/util/src/main/resources/com/ning/billing/util/dao/NonEntitySqlDao.sql.stg
@@ -0,0 +1,67 @@
+group NonEntitySqlDao;
+
+getRecordIdFromObject(tableName) ::= <<
+select
+ record_id
+from <tableName>
+where id = :id
+;
+>>
+
+getAccountRecordIdFromAccountHistory() ::= <<
+select
+ target_record_id
+from account_history
+where id = :id
+;
+>>
+
+getAccountRecordIdFromAccount() ::= <<
+select
+ record_id
+from accounts
+where id = :id
+;
+>>
+
+getAccountRecordIdFromObjectOtherThanAccount(tableName) ::= <<
+select
+ account_record_id
+from <tableName>
+where id = :id
+;
+>>
+
+getTenantRecordIdFromTenant() ::= <<
+select
+ record_id
+from tenants
+where id = :id
+;
+>>
+
+getTenantRecordIdFromObjectOtherThanTenant(tableName) ::= <<
+select
+ tenant_record_id
+from <tableName>
+where id = :id
+;
+>>
+
+
+getLastHistoryRecordId(tableName) ::= <<
+select
+ max(record_id)
+from <tableName>
+where target_record_id = :targetRecordId
+;
+>>
+
+getHistoryTargetRecordId(tableName) ::= <<
+select
+ target_record_id
+from <tableName>
+where record_id = :recordId
+;
+>>
+
util/src/main/resources/ehcache.xml 67(+67 -0)
diff --git a/util/src/main/resources/ehcache.xml b/util/src/main/resources/ehcache.xml
new file mode 100644
index 0000000..ac86fe3
--- /dev/null
+++ b/util/src/main/resources/ehcache.xml
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+ ~ Copyright 2010-2012 Ning, Inc.
+ ~
+ ~ Ning licenses this file to you under the Apache License, version 2.0
+ ~ (the "License"); you may not use this file except in compliance with the
+ ~ License. You may obtain a copy of the License at:
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ ~ WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ ~ License for the specific language governing permissions and limitations
+ ~ under the License.
+ -->
+
+<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:noNamespaceSchemaLocation="ehcache.xsd" >
+
+ <defaultCache
+ maxElementsInMemory="0"
+ maxElementsOnDisk="0"
+ eternal="false"
+ timeToIdleSeconds="0"
+ timeToLiveSeconds="0"
+ overflowToDisk="false"
+ />
+
+ <cache name="record-id"
+ maxElementsInMemory="100000"
+ maxElementsOnDisk="0"
+ eternal="true"
+ overflowToDisk="false"
+ diskPersistent="false"
+ memoryStoreEvictionPolicy="LFU">
+ <cacheEventListenerFactory
+ class="com.ning.billing.util.cache.ExpirationListenerFactory"
+ properties="" />
+ </cache>
+
+ <cache name="tenant-record-id"
+ maxElementsInMemory="100000"
+ maxElementsOnDisk="0"
+ eternal="true"
+ overflowToDisk="false"
+ diskPersistent="false"
+ memoryStoreEvictionPolicy="LFU">
+ <cacheEventListenerFactory
+ class="com.ning.billing.util.cache.ExpirationListenerFactory"
+ properties="" />
+ </cache>
+
+ <cache name="account-record-id"
+ maxElementsInMemory="100000"
+ maxElementsOnDisk="0"
+ eternal="true"
+ overflowToDisk="false"
+ diskPersistent="false"
+ memoryStoreEvictionPolicy="LFU">
+ <cacheEventListenerFactory
+ class="com.ning.billing.util.cache.ExpirationListenerFactory"
+ properties="" />
+ </cache>
+</ehcache>
+
diff --git a/util/src/test/java/com/ning/billing/dao/MockNonEntityDao.java b/util/src/test/java/com/ning/billing/dao/MockNonEntityDao.java
new file mode 100644
index 0000000..4444bdf
--- /dev/null
+++ b/util/src/test/java/com/ning/billing/dao/MockNonEntityDao.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2010-2013 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.dao;
+
+import java.util.UUID;
+
+import javax.annotation.Nullable;
+
+import com.ning.billing.ObjectType;
+import com.ning.billing.util.cache.CacheController;
+import com.ning.billing.util.dao.NonEntityDao;
+import com.ning.billing.util.dao.NonEntitySqlDao;
+import com.ning.billing.util.dao.TableName;
+
+public class MockNonEntityDao implements NonEntityDao {
+
+ @Override
+ public Long retrieveRecordIdFromObject(final UUID objectId, final ObjectType objectType, @Nullable final CacheController<Object, Object> cache) {
+ return null;
+ }
+
+ @Override
+ public Long retrieveAccountRecordIdFromObject(final UUID objectId, final ObjectType objectType, @Nullable final CacheController<Object, Object> cache) {
+ return null;
+ }
+
+ @Override
+ public Long retrieveTenantRecordIdFromObject(final UUID objectId, final ObjectType objectType, @Nullable final CacheController<Object, Object> cache) {
+ return null;
+ }
+
+ @Override
+ public Long retrieveLastHistoryRecordIdFromTransaction(final Long targetRecordId, final TableName tableName, final NonEntitySqlDao transactional) {
+ return null;
+ }
+
+ @Override
+ public Long retrieveHistoryTargetRecordId(final Long recordId, final TableName tableName) {
+ return null;
+ }
+}
diff --git a/util/src/test/java/com/ning/billing/dbi/DBTestingHelper.java b/util/src/test/java/com/ning/billing/dbi/DBTestingHelper.java
index 65a3e9a..a2241c5 100644
--- a/util/src/test/java/com/ning/billing/dbi/DBTestingHelper.java
+++ b/util/src/test/java/com/ning/billing/dbi/DBTestingHelper.java
@@ -47,14 +47,14 @@ public abstract class DBTestingHelper {
protected IDBI dbiInstance = null;
public synchronized IDBI getDBI() {
- if (dbiInstance == null) {
- final String dbiString = getJdbcConnectionString();
- dbiInstance = new DBIProvider(dbiString, USERNAME, PASSWORD).get();
- }
+ createInstanceIfNull();
return dbiInstance;
}
public void initDb() throws IOException {
+
+ createInstanceIfNull();
+
// We always want the accounts and tenants table
initDb("drop table if exists accounts;" +
"CREATE TABLE accounts (\n" +
@@ -87,7 +87,8 @@ public abstract class DBTestingHelper {
" tenant_record_id int(11) unsigned default null,\n" +
" PRIMARY KEY(record_id)\n" +
");");
- initDb("drop table if exists tenants; create table tenants(record_id int(11) unsigned not null auto_increment, id char(36) not null, primary key(record_id));");
+ initDb("drop table if exists tenants; create table tenants(record_id int(11) unsigned not null auto_increment, id char(36) not null, external_key varchar(128) NULL, api_key varchar(128) NULL, " +
+ "api_secret varchar(128) NULL, api_salt varchar(128) NULL, created_date datetime NOT NULL, created_by varchar(50) NOT NULL, updated_date datetime DEFAULT NULL, updated_by varchar(50) DEFAULT NULL, primary key(record_id));");
// We always want the basic tables when we do account_record_id lookups (e.g. for custom fields, tags or junction)
initDb("drop table if exists bundles; create table bundles(record_id int(11) unsigned not null auto_increment, id char(36) not null, " +
@@ -162,4 +163,11 @@ public abstract class DBTestingHelper {
public abstract void start() throws IOException;
public abstract void stop();
+
+ private synchronized void createInstanceIfNull() {
+ if (dbiInstance == null) {
+ final String dbiString = getJdbcConnectionString();
+ dbiInstance = new DBIProvider(dbiString, USERNAME, PASSWORD).get();
+ }
+ }
}
diff --git a/util/src/test/java/com/ning/billing/KillbillTestSuite.java b/util/src/test/java/com/ning/billing/KillbillTestSuite.java
index 667937e..8d7d131 100644
--- a/util/src/test/java/com/ning/billing/KillbillTestSuite.java
+++ b/util/src/test/java/com/ning/billing/KillbillTestSuite.java
@@ -40,7 +40,7 @@ public class KillbillTestSuite {
private boolean hasFailed = false;
- private Clock clock = new ClockMock();
+ protected Clock clock = new ClockMock();
protected final InternalCallContext internalCallContext = new InternalCallContext(InternalCallContextFactory.INTERNAL_TENANT_RECORD_ID, 1687L, UUID.randomUUID(),
UUID.randomUUID().toString(), CallOrigin.TEST,
@@ -59,8 +59,8 @@ public class KillbillTestSuite {
public void endTestSuite(final Method method, final ITestResult result) throws Exception {
log.info("***************************************************************************************************");
log.info("*** Ending test {}:{} {} ({} s.)", new Object[]{method.getDeclaringClass().getName(), method.getName(),
- result.isSuccess() ? "SUCCESS" : "!!! FAILURE !!!",
- (result.getEndMillis() - result.getStartMillis()) / 1000});
+ result.isSuccess() ? "SUCCESS" : "!!! FAILURE !!!",
+ (result.getEndMillis() - result.getStartMillis()) / 1000});
log.info("***************************************************************************************************");
if (!hasFailed && !result.isSuccess()) {
hasFailed = true;
diff --git a/util/src/test/java/com/ning/billing/mock/glue/MockNonEntityDaoModule.java b/util/src/test/java/com/ning/billing/mock/glue/MockNonEntityDaoModule.java
new file mode 100644
index 0000000..4f230e7
--- /dev/null
+++ b/util/src/test/java/com/ning/billing/mock/glue/MockNonEntityDaoModule.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2010-2013 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.mock.glue;
+
+import java.util.UUID;
+
+import javax.annotation.Nullable;
+
+import com.ning.billing.ObjectType;
+import com.ning.billing.dao.MockNonEntityDao;
+import com.ning.billing.util.cache.CacheController;
+import com.ning.billing.util.dao.NonEntityDao;
+import com.ning.billing.util.dao.TableName;
+
+import com.google.inject.AbstractModule;
+
+public class MockNonEntityDaoModule extends AbstractModule {
+
+ @Override
+ protected void configure() {
+ bind(NonEntityDao.class).to(MockNonEntityDao.class);
+ }
+}
diff --git a/util/src/test/java/com/ning/billing/util/audit/dao/TestDefaultAuditDao.java b/util/src/test/java/com/ning/billing/util/audit/dao/TestDefaultAuditDao.java
index d24059a..d1b419d 100644
--- a/util/src/test/java/com/ning/billing/util/audit/dao/TestDefaultAuditDao.java
+++ b/util/src/test/java/com/ning/billing/util/audit/dao/TestDefaultAuditDao.java
@@ -38,10 +38,13 @@ import com.ning.billing.util.api.TagDefinitionApiException;
import com.ning.billing.util.audit.AuditLog;
import com.ning.billing.util.audit.ChangeType;
import com.ning.billing.util.clock.Clock;
+import com.ning.billing.util.dao.NonEntityDao;
import com.ning.billing.util.dao.TableName;
import com.ning.billing.util.glue.AuditModule;
import com.ning.billing.util.glue.BusModule;
+import com.ning.billing.util.glue.CacheModule;
import com.ning.billing.util.glue.ClockModule;
+import com.ning.billing.util.glue.NonEntityDaoModule;
import com.ning.billing.util.glue.TagStoreModule;
import com.ning.billing.util.svcsapi.bus.InternalBus;
import com.ning.billing.util.tag.DescriptiveTag;
@@ -53,7 +56,7 @@ import com.ning.billing.util.tag.dao.TagModelDao;
import com.google.inject.Inject;
-@Guice(modules = {TagStoreModule.class, AuditModule.class, MockEntitlementModule.class, ClockModule.class, BusModule.class, MockDbHelperModule.class})
+@Guice(modules = {TagStoreModule.class, CacheModule.class, AuditModule.class, MockEntitlementModule.class, ClockModule.class, BusModule.class, MockDbHelperModule.class, NonEntityDaoModule.class})
public class TestDefaultAuditDao extends UtilTestSuiteWithEmbeddedDB {
@Inject
diff --git a/util/src/test/java/com/ning/billing/util/bus/TestPersistentEventBus.java b/util/src/test/java/com/ning/billing/util/bus/TestPersistentEventBus.java
index 6d56561..abd8339 100644
--- a/util/src/test/java/com/ning/billing/util/bus/TestPersistentEventBus.java
+++ b/util/src/test/java/com/ning/billing/util/bus/TestPersistentEventBus.java
@@ -29,6 +29,8 @@ import com.ning.billing.util.clock.Clock;
import com.ning.billing.util.clock.ClockMock;
import com.ning.billing.util.glue.BusModule;
import com.ning.billing.util.glue.BusModule.BusType;
+import com.ning.billing.util.glue.CacheModule;
+import com.ning.billing.util.glue.NonEntityDaoModule;
import com.google.inject.AbstractModule;
@@ -54,6 +56,8 @@ public class TestPersistentEventBus extends TestEventBusBase {
bind(IDBI.class).toInstance(dbi);
}
install(new BusModule(BusType.PERSISTENT));
+ install(new NonEntityDaoModule());
+ install(new CacheModule());
}
}
diff --git a/util/src/test/java/com/ning/billing/util/cache/TestCache.java b/util/src/test/java/com/ning/billing/util/cache/TestCache.java
new file mode 100644
index 0000000..1fcbf39
--- /dev/null
+++ b/util/src/test/java/com/ning/billing/util/cache/TestCache.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.util.cache;
+
+import java.util.UUID;
+
+import javax.inject.Inject;
+
+import org.testng.Assert;
+import org.testng.annotations.Guice;
+import org.testng.annotations.Test;
+
+import com.ning.billing.ObjectType;
+import com.ning.billing.mock.glue.MockDbHelperModule;
+import com.ning.billing.util.UtilTestSuiteWithEmbeddedDB;
+import com.ning.billing.util.cache.Cachable.CacheType;
+import com.ning.billing.util.dao.NonEntityDao;
+import com.ning.billing.util.entity.dao.EntitySqlDao;
+import com.ning.billing.util.entity.dao.EntitySqlDaoTransactionWrapper;
+import com.ning.billing.util.entity.dao.EntitySqlDaoTransactionalJdbiWrapper;
+import com.ning.billing.util.entity.dao.EntitySqlDaoWrapperFactory;
+import com.ning.billing.util.glue.CacheModule;
+import com.ning.billing.util.glue.ClockModule;
+import com.ning.billing.util.glue.NonEntityDaoModule;
+import com.ning.billing.util.tag.dao.TagModelDao;
+import com.ning.billing.util.tag.dao.TagSqlDao;
+
+@Guice(modules = {ClockModule.class, CacheModule.class, MockDbHelperModule.class, NonEntityDaoModule.class } )
+public class TestCache extends UtilTestSuiteWithEmbeddedDB {
+
+ @Inject
+ private CacheControllerDispatcher controlCacheDispatcher;
+
+ @Inject
+ private NonEntityDao nonEntityDao;
+
+ private EntitySqlDaoTransactionalJdbiWrapper transactionalSqlDao;
+
+
+ private void insertTag(final TagModelDao modelDao) {
+ transactionalSqlDao.execute(new EntitySqlDaoTransactionWrapper<Void>() {
+ @Override
+ public Void inTransaction(final EntitySqlDaoWrapperFactory<EntitySqlDao> entitySqlDaoWrapperFactory) throws Exception {
+ entitySqlDaoWrapperFactory.become(TagSqlDao.class).create(modelDao, internalCallContext);
+ return null;
+ }
+ });
+ }
+
+ private Long getTagRecordId(final UUID tagId) {
+ return transactionalSqlDao.execute(new EntitySqlDaoTransactionWrapper<Long>() {
+ @Override
+ public Long inTransaction(final EntitySqlDaoWrapperFactory<EntitySqlDao> entitySqlDaoWrapperFactory) throws Exception {
+ return entitySqlDaoWrapperFactory.become(TagSqlDao.class).getRecordId(tagId.toString(), internalCallContext);
+ }
+ });
+ }
+
+ private int getCacheSize() {
+ final CacheController<Object, Object> cache = controlCacheDispatcher.getCacheController(CacheType.RECORD_ID);
+ return cache != null ? cache.size() : 0;
+ }
+
+ private Long retrieveRecordIdFromCache(UUID tagId) {
+ final CacheController<Object, Object> cache = controlCacheDispatcher.getCacheController(CacheType.RECORD_ID);
+ Object result = null;
+ if (cache != null) {
+ result = cache.get(tagId.toString(), ObjectType.TAG);
+ }
+ return (Long) result;
+ }
+
+ @Test(groups = "slow")
+ public void testCacheRecordId() throws Exception {
+
+ this.transactionalSqlDao = new EntitySqlDaoTransactionalJdbiWrapper(getDBI(), clock, controlCacheDispatcher, nonEntityDao);
+ final TagModelDao tag = new TagModelDao(clock.getUTCNow(), UUID.randomUUID(), UUID.randomUUID(), ObjectType.TAG);
+
+ // Verify we start with nothing in the cache
+ Assert.assertEquals(getCacheSize(), 0);
+ insertTag(tag);
+
+ // Verify we still have nothing after insert in the cache
+ Assert.assertEquals(getCacheSize(), 0);
+
+ final Long tagRecordId = getTagRecordId(tag.getId());
+ // Verify we now have something in the cache
+ Assert.assertEquals(getCacheSize(), 1);
+
+ final Long recordIdFromCache = retrieveRecordIdFromCache(tag.getId());
+ Assert.assertNotNull(recordIdFromCache);
+
+ Assert.assertEquals(recordIdFromCache, new Long(1));
+ Assert.assertEquals(tagRecordId, new Long(1));
+
+ Assert.assertEquals(getCacheSize(), 1);
+ }
+}
diff --git a/util/src/test/java/com/ning/billing/util/callcontext/TestInternalCallContextFactory.java b/util/src/test/java/com/ning/billing/util/callcontext/TestInternalCallContextFactory.java
index e62e51f..b3d9e4e 100644
--- a/util/src/test/java/com/ning/billing/util/callcontext/TestInternalCallContextFactory.java
+++ b/util/src/test/java/com/ning/billing/util/callcontext/TestInternalCallContextFactory.java
@@ -27,15 +27,22 @@ import org.testng.annotations.Test;
import com.ning.billing.ObjectType;
import com.ning.billing.util.UtilTestSuiteWithEmbeddedDB;
+import com.ning.billing.util.cache.CacheControllerDispatcher;
import com.ning.billing.util.clock.ClockMock;
+import com.ning.billing.util.dao.DefaultNonEntityDao;
+import com.ning.billing.util.dao.NonEntityDao;
public class TestInternalCallContextFactory extends UtilTestSuiteWithEmbeddedDB {
private InternalCallContextFactory internalCallContextFactory;
+ private CacheControllerDispatcher cacheControllerDispatcher;
+ private NonEntityDao nonEntityDao;
@BeforeMethod(groups = "slow")
public void setUp() throws Exception {
- internalCallContextFactory = new InternalCallContextFactory(getDBI(), new ClockMock());
+ cacheControllerDispatcher = new CacheControllerDispatcher();
+ nonEntityDao = new DefaultNonEntityDao(getDBI());
+ internalCallContextFactory = new InternalCallContextFactory(new ClockMock(), nonEntityDao, cacheControllerDispatcher);
}
@Test(groups = "slow")
@@ -83,7 +90,7 @@ public class TestInternalCallContextFactory extends UtilTestSuiteWithEmbeddedDB
public Void withHandle(final Handle handle) throws Exception {
// Note: we always create an accounts table, see MysqlTestingHelper
handle.execute("insert into accounts (record_id, id, email, name, first_name_length, is_notified_for_invoices, created_date, created_by, updated_date, updated_by) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
- accountRecordId, accountId.toString(), "yo@t.com", "toto", 4, false, new Date(), "i", new Date(), "j");
+ accountRecordId, accountId.toString(), "yo@t.com", "toto", 4, false, new Date(), "i", new Date(), "j");
return null;
}
});
diff --git a/util/src/test/java/com/ning/billing/util/customfield/api/TestDefaultCustomFieldUserApi.java b/util/src/test/java/com/ning/billing/util/customfield/api/TestDefaultCustomFieldUserApi.java
index 76661c2..bff019c 100644
--- a/util/src/test/java/com/ning/billing/util/customfield/api/TestDefaultCustomFieldUserApi.java
+++ b/util/src/test/java/com/ning/billing/util/customfield/api/TestDefaultCustomFieldUserApi.java
@@ -29,12 +29,15 @@ import org.testng.annotations.Test;
import com.ning.billing.ObjectType;
import com.ning.billing.util.UtilTestSuiteWithEmbeddedDB;
+import com.ning.billing.util.cache.CacheControllerDispatcher;
import com.ning.billing.util.callcontext.InternalCallContextFactory;
import com.ning.billing.util.clock.ClockMock;
import com.ning.billing.util.customfield.CustomField;
import com.ning.billing.util.customfield.StringCustomField;
import com.ning.billing.util.customfield.dao.DefaultCustomFieldDao;
import com.ning.billing.util.customfield.dao.CustomFieldDao;
+import com.ning.billing.util.dao.DefaultNonEntityDao;
+import com.ning.billing.util.dao.NonEntityDao;
import com.google.common.collect.ImmutableList;
@@ -42,10 +45,13 @@ public class TestDefaultCustomFieldUserApi extends UtilTestSuiteWithEmbeddedDB {
private DefaultCustomFieldUserApi customFieldUserApi;
+ private CacheControllerDispatcher controllerDispatcher = new CacheControllerDispatcher();
+
@BeforeMethod(groups = "slow")
public void setUp() throws Exception {
- final InternalCallContextFactory internalCallContextFactory = new InternalCallContextFactory(getDBI(), new ClockMock());
- final CustomFieldDao customFieldDao = new DefaultCustomFieldDao(getDBI());
+ final NonEntityDao nonEntityDao = new DefaultNonEntityDao(getDBI());
+ final InternalCallContextFactory internalCallContextFactory = new InternalCallContextFactory(new ClockMock(), nonEntityDao, controllerDispatcher);
+ final CustomFieldDao customFieldDao = new DefaultCustomFieldDao(getDBI(), clock, controllerDispatcher, nonEntityDao);
customFieldUserApi = new DefaultCustomFieldUserApi(internalCallContextFactory, customFieldDao);
}
diff --git a/util/src/test/java/com/ning/billing/util/customfield/TestFieldStore.java b/util/src/test/java/com/ning/billing/util/customfield/TestFieldStore.java
index da7a8b7..6d0a494 100644
--- a/util/src/test/java/com/ning/billing/util/customfield/TestFieldStore.java
+++ b/util/src/test/java/com/ning/billing/util/customfield/TestFieldStore.java
@@ -28,9 +28,12 @@ import org.testng.annotations.Test;
import com.ning.billing.ObjectType;
import com.ning.billing.util.UtilTestSuiteWithEmbeddedDB;
import com.ning.billing.util.api.CustomFieldApiException;
+import com.ning.billing.util.cache.CacheControllerDispatcher;
import com.ning.billing.util.customfield.dao.CustomFieldDao;
import com.ning.billing.util.customfield.dao.CustomFieldModelDao;
import com.ning.billing.util.customfield.dao.DefaultCustomFieldDao;
+import com.ning.billing.util.dao.DefaultNonEntityDao;
+import com.ning.billing.util.dao.NonEntityDao;
import static org.testng.Assert.fail;
@@ -39,11 +42,14 @@ public class TestFieldStore extends UtilTestSuiteWithEmbeddedDB {
private final Logger log = LoggerFactory.getLogger(TestFieldStore.class);
private CustomFieldDao customFieldDao;
+ private CacheControllerDispatcher controllerDispatcher = new CacheControllerDispatcher();
+
@BeforeClass(groups = "slow")
protected void setup() throws IOException {
try {
final IDBI dbi = getDBI();
- customFieldDao = new DefaultCustomFieldDao(dbi);
+ final NonEntityDao nonEntityDao = new DefaultNonEntityDao(dbi);
+ customFieldDao = new DefaultCustomFieldDao(dbi, clock, controllerDispatcher, nonEntityDao);
} catch (Throwable t) {
log.error("Setup failed", t);
fail(t.toString());
diff --git a/util/src/test/java/com/ning/billing/util/dao/TestNonEntityDao.java b/util/src/test/java/com/ning/billing/util/dao/TestNonEntityDao.java
new file mode 100644
index 0000000..5090226
--- /dev/null
+++ b/util/src/test/java/com/ning/billing/util/dao/TestNonEntityDao.java
@@ -0,0 +1,186 @@
+/*
+ * Copyright 2010-2013 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.util.dao;
+
+import java.util.Date;
+import java.util.UUID;
+
+import org.skife.jdbi.v2.Handle;
+import org.skife.jdbi.v2.tweak.HandleCallback;
+import org.testng.Assert;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import com.ning.billing.ObjectType;
+import com.ning.billing.util.UtilTestSuiteWithEmbeddedDB;
+
+public class TestNonEntityDao extends UtilTestSuiteWithEmbeddedDB {
+
+
+ final Long tenantRecordId = 123123123L;
+ final UUID tenantId = UUID.fromString("121c59d4-0458-4038-a683-698c9a121c12");
+
+
+ final UUID accountId = UUID.fromString("a01c59d4-0458-4038-a683-698c9a121c69");
+ final Long accountRecordId = 333333L;
+
+ final UUID accountHistoryId = UUID.fromString("2b1c59d4-0458-4038-a683-698c9a121c78");
+ final Long accountHistoryRecordId = 777777L;
+
+ final UUID tagDefinitionId = UUID.fromString("e01c59d4-0458-4038-a683-698c9a121c34");
+ final Long tagDefinitionRecordId = 44444444L;
+
+ final UUID tagId = UUID.fromString("123c59d4-0458-4038-a683-698c9a121456");
+ final Long tagRecordId = 55555555L;
+
+
+ private NonEntityDao nonEntityDao;
+
+ @BeforeClass(groups = "slow")
+ public void setup() {
+ nonEntityDao = new DefaultNonEntityDao(getDBI());
+ }
+
+
+ @Test(groups = "slow")
+ public void testRetrieveRecordIdFromObject() {
+
+ insertAccount();
+
+ final Long resultRecordId = nonEntityDao.retrieveRecordIdFromObject(accountId, ObjectType.ACCOUNT, null);
+ Assert.assertEquals(resultRecordId, accountRecordId);
+ }
+
+ @Test(groups = "slow")
+ public void testRetrieveAccountRecordIdFromAccountObject() {
+
+ insertAccount();
+
+ final Long resultAccountRecordId = nonEntityDao.retrieveAccountRecordIdFromObject(accountId, ObjectType.ACCOUNT, null);
+ Assert.assertEquals(resultAccountRecordId, accountRecordId);
+ }
+
+
+ @Test(groups = "slow")
+ public void testRetrieveAccountRecordIdFromTagDefinitionObject() {
+
+ insertTagDefinition();
+
+ final Long resultAccountRecordId = nonEntityDao.retrieveAccountRecordIdFromObject(tagDefinitionId, ObjectType.TAG_DEFINITION, null);
+ Assert.assertEquals(resultAccountRecordId, null);
+ }
+
+ // Not Tag_definition or account which are special
+ @Test(groups = "slow")
+ public void testRetrieveAccountRecordIdFromOtherObject() {
+
+ insertTag();
+
+ final Long resultAccountRecordId = nonEntityDao.retrieveAccountRecordIdFromObject(tagId, ObjectType.TAG, null);
+ Assert.assertEquals(resultAccountRecordId, accountRecordId);
+ }
+
+ @Test(groups = "slow")
+ public void testRetrieveTenantRecordIdFromObject() {
+
+ insertAccount();
+
+ final Long resultTenantRecordId = nonEntityDao.retrieveTenantRecordIdFromObject(accountId, ObjectType.ACCOUNT,null);
+ Assert.assertEquals(resultTenantRecordId, tenantRecordId);
+ }
+
+ @Test(groups = "slow")
+ public void testRetrieveTenantRecordIdFromTenantObject() {
+
+ insertTenant();
+
+ final Long resultTenantRecordId = nonEntityDao.retrieveTenantRecordIdFromObject(tenantId, ObjectType.TENANT, null);
+ Assert.assertEquals(resultTenantRecordId, tenantRecordId);
+ }
+
+ /*
+ @Test(groups = "slow")
+ public void testRetrieveTenantRecordIdFromTenantObject() {
+
+ insertTenant();
+
+ final Long resultTenantRecordId = nonEntityDao.retrieveLastHistoryRecordIdFromTransaction();
+ Assert.assertEquals(resultTenantRecordId, tenantRecordId);
+ }
+*/
+
+ private void insertAccount() {
+ getDBI().withHandle(new HandleCallback<Void>() {
+ @Override
+ public Void withHandle(final Handle handle) throws Exception {
+ // Note: we always create an accounts table, see MysqlTestingHelper
+ handle.execute("insert into accounts (record_id, id, email, name, first_name_length, is_notified_for_invoices, created_date, created_by, updated_date, updated_by, tenant_record_id) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
+ accountRecordId, accountId.toString(), "zozo@tt.com", "zozo", 4, false, new Date(), "i", new Date(), "j", tenantRecordId);
+ return null;
+ }
+ });
+ }
+
+ private void insertHistoryAccount() {
+ getDBI().withHandle(new HandleCallback<Void>() {
+ @Override
+ public Void withHandle(final Handle handle) throws Exception {
+ // Note: we always create an accounts table, see MysqlTestingHelper
+ handle.execute("insert into account_history (record_id, id, email, name, first_name_length, is_notified_for_invoices, created_date, created_by, updated_date, updated_by, tenant_record_id) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
+ accountRecordId, accountId.toString(), "zozo@tt.com", "zozo", 4, false, new Date(), "i", new Date(), "j", tenantRecordId);
+ return null;
+ }
+ });
+ }
+
+
+ private void insertTagDefinition() {
+ getDBI().withHandle(new HandleCallback<Void>() {
+ @Override
+ public Void withHandle(final Handle handle) throws Exception {
+ // Note: we always create an accounts table, see MysqlTestingHelper
+ handle.execute("insert into tag_definitions (record_id, id, name, description, is_active, created_date, created_by, updated_date, updated_by, tenant_record_id) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
+ tagDefinitionRecordId, tagDefinitionId.toString(), "tagdef", "nothing", 1, new Date(), "i", new Date(), "j", 0);
+ return null;
+ }
+ });
+ }
+
+ private void insertTag() {
+ getDBI().withHandle(new HandleCallback<Void>() {
+ @Override
+ public Void withHandle(final Handle handle) throws Exception {
+ // Note: we always create an accounts table, see MysqlTestingHelper
+ handle.execute("insert into tags (record_id, id, tag_definition_id, object_id, object_type, is_active, created_date, created_by, updated_date, updated_by, account_record_id, tenant_record_id) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
+ tagRecordId, tagId.toString(), tagDefinitionId.toString(), accountId.toString(), "ACCOUNT", 1, new Date(), "i", new Date(), "j", accountRecordId, 0);
+ return null;
+ }
+ });
+ }
+
+ private void insertTenant() {
+ getDBI().withHandle(new HandleCallback<Void>() {
+ @Override
+ public Void withHandle(final Handle handle) throws Exception {
+ // Note: we always create an accounts table, see MysqlTestingHelper
+ handle.execute("insert into tenants (record_id, id, external_key, api_key, api_secret, api_salt, created_date, created_by, updated_date, updated_by) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
+ tenantRecordId, tenantId.toString(), "foo", "key", "secret", "salt", new Date(), "i", new Date(), "j");
+ return null;
+ }
+ });
+ }
+}
diff --git a/util/src/test/java/com/ning/billing/util/notificationq/TestNotificationQueue.java b/util/src/test/java/com/ning/billing/util/notificationq/TestNotificationQueue.java
index b0f4e74..79dbb01 100644
--- a/util/src/test/java/com/ning/billing/util/notificationq/TestNotificationQueue.java
+++ b/util/src/test/java/com/ning/billing/util/notificationq/TestNotificationQueue.java
@@ -34,12 +34,16 @@ import org.testng.annotations.Guice;
import org.testng.annotations.Test;
import com.ning.billing.util.UtilTestSuiteWithEmbeddedDB;
+import com.ning.billing.util.cache.CacheControllerDispatcher;
import com.ning.billing.util.clock.Clock;
import com.ning.billing.util.clock.ClockMock;
+import com.ning.billing.util.dao.NonEntityDao;
import com.ning.billing.util.entity.dao.EntitySqlDao;
import com.ning.billing.util.entity.dao.EntitySqlDaoTransactionWrapper;
import com.ning.billing.util.entity.dao.EntitySqlDaoTransactionalJdbiWrapper;
import com.ning.billing.util.entity.dao.EntitySqlDaoWrapperFactory;
+import com.ning.billing.util.glue.CacheModule;
+import com.ning.billing.util.glue.NonEntityDaoModule;
import com.ning.billing.util.io.IOUtils;
import com.ning.billing.util.notificationq.NotificationQueueService.NotificationQueueHandler;
import com.ning.billing.util.notificationq.dao.NotificationSqlDao;
@@ -56,7 +60,7 @@ import static com.jayway.awaitility.Awaitility.await;
import static java.util.concurrent.TimeUnit.MINUTES;
import static org.testng.Assert.assertEquals;
-@Guice(modules = TestNotificationQueue.TestNotificationQueueModule.class)
+@Guice(modules = {TestNotificationQueue.TestNotificationQueueModule.class, CacheModule.class, NonEntityDaoModule.class})
public class TestNotificationQueue extends UtilTestSuiteWithEmbeddedDB {
private final Logger log = LoggerFactory.getLogger(TestNotificationQueue.class);
@@ -70,7 +74,14 @@ public class TestNotificationQueue extends UtilTestSuiteWithEmbeddedDB {
private Clock clock;
@Inject
- NotificationQueueService queueService;
+ private NotificationQueueService queueService;
+
+ @Inject
+ private CacheControllerDispatcher controllerDispatcher;
+
+ @Inject
+ private NonEntityDao nonEntityDao;
+
private int eventsReceived;
@@ -105,7 +116,7 @@ public class TestNotificationQueue extends UtilTestSuiteWithEmbeddedDB {
public void setup() throws Exception {
final String testDdl = IOUtils.toString(NotificationSqlDao.class.getResourceAsStream("/com/ning/billing/util/ddl_test.sql"));
helper.initDb(testDdl);
- entitySqlDaoTransactionalJdbiWrapper = new EntitySqlDaoTransactionalJdbiWrapper(dbi);
+ entitySqlDaoTransactionalJdbiWrapper = new EntitySqlDaoTransactionalJdbiWrapper(dbi, clock, controllerDispatcher, nonEntityDao);
}
@BeforeTest(groups = "slow")
diff --git a/util/src/test/java/com/ning/billing/util/tag/dao/TestDefaultTagDao.java b/util/src/test/java/com/ning/billing/util/tag/dao/TestDefaultTagDao.java
index 548a65a..fb2cac3 100644
--- a/util/src/test/java/com/ning/billing/util/tag/dao/TestDefaultTagDao.java
+++ b/util/src/test/java/com/ning/billing/util/tag/dao/TestDefaultTagDao.java
@@ -36,7 +36,9 @@ import com.ning.billing.util.bus.InMemoryBusModule;
import com.ning.billing.util.clock.Clock;
import com.ning.billing.util.events.BusInternalEvent;
import com.ning.billing.util.events.TagInternalEvent;
+import com.ning.billing.util.glue.CacheModule;
import com.ning.billing.util.glue.ClockModule;
+import com.ning.billing.util.glue.NonEntityDaoModule;
import com.ning.billing.util.glue.TagStoreModule;
import com.ning.billing.util.svcsapi.bus.InternalBus;
import com.ning.billing.util.tag.ControlTagType;
@@ -48,7 +50,7 @@ import com.google.inject.Inject;
import static org.testng.Assert.assertEquals;
-@Guice(modules = {TagStoreModule.class, ClockModule.class, InMemoryBusModule.class, MockDbHelperModule.class})
+@Guice(modules = {TagStoreModule.class, CacheModule.class, ClockModule.class, InMemoryBusModule.class, MockDbHelperModule.class, NonEntityDaoModule.class})
public class TestDefaultTagDao extends UtilTestSuiteWithEmbeddedDB {
@Inject
diff --git a/util/src/test/java/com/ning/billing/util/tag/dao/TestDefaultTagDefinitionDao.java b/util/src/test/java/com/ning/billing/util/tag/dao/TestDefaultTagDefinitionDao.java
index 46fe94c..8287661 100644
--- a/util/src/test/java/com/ning/billing/util/tag/dao/TestDefaultTagDefinitionDao.java
+++ b/util/src/test/java/com/ning/billing/util/tag/dao/TestDefaultTagDefinitionDao.java
@@ -34,14 +34,16 @@ import com.ning.billing.util.bus.InMemoryBusModule;
import com.ning.billing.util.clock.Clock;
import com.ning.billing.util.events.BusInternalEvent;
import com.ning.billing.util.events.TagDefinitionInternalEvent;
+import com.ning.billing.util.glue.CacheModule;
import com.ning.billing.util.glue.ClockModule;
+import com.ning.billing.util.glue.NonEntityDaoModule;
import com.ning.billing.util.glue.TagStoreModule;
import com.ning.billing.util.svcsapi.bus.InternalBus;
import com.google.common.eventbus.Subscribe;
import com.google.inject.Inject;
-@Guice(modules = {TagStoreModule.class, ClockModule.class, InMemoryBusModule.class, MockDbHelperModule.class})
+@Guice(modules = {TagStoreModule.class, CacheModule.class, ClockModule.class, InMemoryBusModule.class, MockDbHelperModule.class, NonEntityDaoModule.class})
public class TestDefaultTagDefinitionDao extends UtilTestSuiteWithEmbeddedDB {
@Inject
diff --git a/util/src/test/java/com/ning/billing/util/tag/TestTagStore.java b/util/src/test/java/com/ning/billing/util/tag/TestTagStore.java
index cd218de..29b76c0 100644
--- a/util/src/test/java/com/ning/billing/util/tag/TestTagStore.java
+++ b/util/src/test/java/com/ning/billing/util/tag/TestTagStore.java
@@ -36,7 +36,9 @@ import com.ning.billing.util.api.TagApiException;
import com.ning.billing.util.api.TagDefinitionApiException;
import com.ning.billing.util.clock.Clock;
import com.ning.billing.util.glue.BusModule;
+import com.ning.billing.util.glue.CacheModule;
import com.ning.billing.util.glue.ClockModule;
+import com.ning.billing.util.glue.NonEntityDaoModule;
import com.ning.billing.util.glue.TagStoreModule;
import com.ning.billing.util.svcsapi.bus.InternalBus;
import com.ning.billing.util.tag.dao.TagDao;
@@ -53,7 +55,7 @@ import static org.testng.Assert.assertTrue;
import static org.testng.Assert.fail;
@Test(groups = {"slow"})
-@Guice(modules = {TagStoreModule.class, ClockModule.class, BusModule.class, MockDbHelperModule.class})
+@Guice(modules = {TagStoreModule.class, ClockModule.class, BusModule.class, CacheModule.class, MockDbHelperModule.class, NonEntityDaoModule.class})
public class TestTagStore extends UtilTestSuiteWithEmbeddedDB {
@Inject