killbill-memoizeit
Changes
osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/AnalyticsListener.java 22(+20 -2)
Details
diff --git a/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/AnalyticsListener.java b/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/AnalyticsListener.java
index 3a18bb0..5e2afc3 100644
--- a/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/AnalyticsListener.java
+++ b/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/AnalyticsListener.java
@@ -27,6 +27,7 @@ import com.ning.billing.beatrix.bus.api.ExtBusEvent;
import com.ning.billing.commons.locker.GlobalLock;
import com.ning.billing.commons.locker.GlobalLocker;
import com.ning.billing.commons.locker.mysql.MySqlGlobalLocker;
+import com.ning.billing.osgi.bundles.analytics.dao.AllBusinessObjectsDao;
import com.ning.billing.osgi.bundles.analytics.dao.BusinessAccountDao;
import com.ning.billing.osgi.bundles.analytics.dao.BusinessFieldDao;
import com.ning.billing.osgi.bundles.analytics.dao.BusinessInvoiceAndInvoicePaymentDao;
@@ -53,6 +54,7 @@ public class AnalyticsListener implements OSGIKillbillEventHandler {
private final BusinessOverdueStatusDao bosDao;
private final BusinessFieldDao bFieldDao;
private final BusinessTagDao bTagDao;
+ private final AllBusinessObjectsDao allBusinessObjectsDao;
private final GlobalLocker locker;
public AnalyticsListener(final OSGIKillbillLogService logService,
@@ -66,7 +68,9 @@ public class AnalyticsListener implements OSGIKillbillEventHandler {
this.bosDao = new BusinessOverdueStatusDao(logService, osgiKillbillAPI, osgiKillbillDataSource);
this.bFieldDao = new BusinessFieldDao(logService, osgiKillbillAPI, osgiKillbillDataSource);
this.bTagDao = new BusinessTagDao(logService, osgiKillbillAPI, osgiKillbillDataSource);
+ this.allBusinessObjectsDao = new AllBusinessObjectsDao(logService, osgiKillbillAPI, osgiKillbillDataSource);
+ // TODO Do we still need it?
this.locker = new MySqlGlobalLocker(osgiKillbillDataSource.getDataSource());
}
@@ -77,7 +81,9 @@ public class AnalyticsListener implements OSGIKillbillEventHandler {
switch (killbillEvent.getEventType()) {
case ACCOUNT_CREATION:
case ACCOUNT_CHANGE:
- handleAccountEvent(killbillEvent, callContext);
+ // Note: account information is denormalized across all tables, we pretty much
+ // have to refresh all objects
+ handleFullRefreshEvent(killbillEvent, callContext);
break;
case SUBSCRIPTION_CREATION:
case SUBSCRIPTION_CHANGE:
@@ -97,7 +103,9 @@ public class AnalyticsListener implements OSGIKillbillEventHandler {
break;
case TAG_CREATION:
case TAG_DELETION:
- handleTagEvent(killbillEvent, callContext);
+ // Note: tags determine the report group. Since it is denormalized across all tables, we pretty much
+ // have to refresh all objects
+ handleFullRefreshEvent(killbillEvent, callContext);
break;
case CUSTOM_FIELD_CREATION:
case CUSTOM_FIELD_DELETION:
@@ -178,6 +186,16 @@ public class AnalyticsListener implements OSGIKillbillEventHandler {
});
}
+ private void handleFullRefreshEvent(final ExtBusEvent killbillEvent, final CallContext callContext) {
+ updateWithAccountLock(killbillEvent, new Callable<Void>() {
+ @Override
+ public Void call() throws Exception {
+ allBusinessObjectsDao.update(killbillEvent.getAccountId(), callContext);
+ return null;
+ }
+ });
+ }
+
private static final class AnalyticsCallContext implements CallContext {
private static final String USER_NAME = AnalyticsListener.class.getName();
diff --git a/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/api/user/AnalyticsUserApi.java b/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/api/user/AnalyticsUserApi.java
index 1c53388..b2ac8b4 100644
--- a/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/api/user/AnalyticsUserApi.java
+++ b/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/api/user/AnalyticsUserApi.java
@@ -19,9 +19,6 @@ package com.ning.billing.osgi.bundles.analytics.api.user;
import java.util.Collection;
import java.util.UUID;
-import org.osgi.service.log.LogService;
-
-import com.ning.billing.ObjectType;
import com.ning.billing.osgi.bundles.analytics.AnalyticsRefreshException;
import com.ning.billing.osgi.bundles.analytics.api.BusinessAccount;
import com.ning.billing.osgi.bundles.analytics.api.BusinessField;
@@ -31,13 +28,8 @@ import com.ning.billing.osgi.bundles.analytics.api.BusinessOverdueStatus;
import com.ning.billing.osgi.bundles.analytics.api.BusinessSnapshot;
import com.ning.billing.osgi.bundles.analytics.api.BusinessSubscriptionTransition;
import com.ning.billing.osgi.bundles.analytics.api.BusinessTag;
+import com.ning.billing.osgi.bundles.analytics.dao.AllBusinessObjectsDao;
import com.ning.billing.osgi.bundles.analytics.dao.AnalyticsDao;
-import com.ning.billing.osgi.bundles.analytics.dao.BusinessAccountDao;
-import com.ning.billing.osgi.bundles.analytics.dao.BusinessFieldDao;
-import com.ning.billing.osgi.bundles.analytics.dao.BusinessInvoiceAndInvoicePaymentDao;
-import com.ning.billing.osgi.bundles.analytics.dao.BusinessOverdueStatusDao;
-import com.ning.billing.osgi.bundles.analytics.dao.BusinessSubscriptionTransitionDao;
-import com.ning.billing.osgi.bundles.analytics.dao.BusinessTagDao;
import com.ning.billing.util.callcontext.CallContext;
import com.ning.billing.util.callcontext.TenantContext;
import com.ning.killbill.osgi.libs.killbill.OSGIKillbillAPI;
@@ -46,26 +38,14 @@ import com.ning.killbill.osgi.libs.killbill.OSGIKillbillLogService;
public class AnalyticsUserApi {
- private final LogService logService;
private final AnalyticsDao analyticsDao;
- private final BusinessSubscriptionTransitionDao bstDao;
- private final BusinessInvoiceAndInvoicePaymentDao binAndBipDao;
- private final BusinessOverdueStatusDao bosDao;
- private final BusinessFieldDao bFieldDao;
- private final BusinessTagDao bTagDao;
+ private final AllBusinessObjectsDao allBusinessObjectsDao;
public AnalyticsUserApi(final OSGIKillbillLogService logService,
final OSGIKillbillAPI osgiKillbillAPI,
final OSGIKillbillDataSource osgiKillbillDataSource) {
- this.logService = logService;
this.analyticsDao = new AnalyticsDao(logService, osgiKillbillAPI, osgiKillbillDataSource);
-
- final BusinessAccountDao bacDao = new BusinessAccountDao(logService, osgiKillbillAPI, osgiKillbillDataSource);
- this.bstDao = new BusinessSubscriptionTransitionDao(logService, osgiKillbillAPI, osgiKillbillDataSource, bacDao);
- this.binAndBipDao = new BusinessInvoiceAndInvoicePaymentDao(logService, osgiKillbillAPI, osgiKillbillDataSource, bacDao);
- this.bosDao = new BusinessOverdueStatusDao(logService, osgiKillbillAPI, osgiKillbillDataSource);
- this.bFieldDao = new BusinessFieldDao(logService, osgiKillbillAPI, osgiKillbillDataSource);
- this.bTagDao = new BusinessTagDao(logService, osgiKillbillAPI, osgiKillbillDataSource);
+ this.allBusinessObjectsDao = new AllBusinessObjectsDao(logService, osgiKillbillAPI, osgiKillbillDataSource);
}
public BusinessSnapshot getBusinessSnapshot(final UUID accountId, final TenantContext context) {
@@ -98,23 +78,7 @@ public class AnalyticsUserApi {
}
public void rebuildAnalyticsForAccount(final UUID accountId, final CallContext context) throws AnalyticsRefreshException {
- logService.log(LogService.LOG_INFO, "Starting rebuild of Analytics for account " + accountId);
-
- // Refresh invoices and payments. This will automatically trigger a refresh of account
- binAndBipDao.update(accountId, context);
-
- // Refresh BST
- bstDao.update(accountId, context);
-
- // Refresh tags
- bTagDao.update(accountId, context);
-
- // Refresh fields
- bFieldDao.update(accountId, context);
-
- // Refresh BOS (bundles only for now)
- bosDao.update(accountId, ObjectType.BUNDLE, context);
-
- logService.log(LogService.LOG_INFO, "Finished rebuild of Analytics for account " + accountId);
+ // TODO Should we take the account lock?
+ allBusinessObjectsDao.update(accountId, context);
}
}
diff --git a/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/AllBusinessObjectsDao.java b/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/AllBusinessObjectsDao.java
new file mode 100644
index 0000000..49f95d8
--- /dev/null
+++ b/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/AllBusinessObjectsDao.java
@@ -0,0 +1,73 @@
+/*
+ * 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.osgi.bundles.analytics.dao;
+
+import java.util.UUID;
+
+import org.osgi.service.log.LogService;
+
+import com.ning.billing.ObjectType;
+import com.ning.billing.osgi.bundles.analytics.AnalyticsRefreshException;
+import com.ning.billing.util.callcontext.CallContext;
+import com.ning.killbill.osgi.libs.killbill.OSGIKillbillAPI;
+import com.ning.killbill.osgi.libs.killbill.OSGIKillbillDataSource;
+import com.ning.killbill.osgi.libs.killbill.OSGIKillbillLogService;
+
+public class AllBusinessObjectsDao {
+
+ private final LogService logService;
+ private final BusinessSubscriptionTransitionDao bstDao;
+ private final BusinessInvoiceAndInvoicePaymentDao binAndBipDao;
+ private final BusinessOverdueStatusDao bosDao;
+ private final BusinessFieldDao bFieldDao;
+ private final BusinessTagDao bTagDao;
+
+ public AllBusinessObjectsDao(final OSGIKillbillLogService logService,
+ final OSGIKillbillAPI osgiKillbillAPI,
+ final OSGIKillbillDataSource osgiKillbillDataSource) {
+ this.logService = logService;
+
+ final BusinessAccountDao bacDao = new BusinessAccountDao(logService, osgiKillbillAPI, osgiKillbillDataSource);
+ this.bstDao = new BusinessSubscriptionTransitionDao(logService, osgiKillbillAPI, osgiKillbillDataSource, bacDao);
+ this.binAndBipDao = new BusinessInvoiceAndInvoicePaymentDao(logService, osgiKillbillAPI, osgiKillbillDataSource, bacDao);
+ this.bosDao = new BusinessOverdueStatusDao(logService, osgiKillbillAPI, osgiKillbillDataSource);
+ this.bFieldDao = new BusinessFieldDao(logService, osgiKillbillAPI, osgiKillbillDataSource);
+ this.bTagDao = new BusinessTagDao(logService, osgiKillbillAPI, osgiKillbillDataSource);
+ }
+
+ // TODO: each refresh is done in a transaction - do we want to share a long running transaction across all refreshes?
+ public void update(final UUID accountId, final CallContext context) throws AnalyticsRefreshException {
+ logService.log(LogService.LOG_INFO, "Starting rebuild of Analytics for account " + accountId);
+
+ // Refresh invoices and payments. This will automatically trigger a refresh of account
+ binAndBipDao.update(accountId, context);
+
+ // Refresh BST
+ bstDao.update(accountId, context);
+
+ // Refresh tags
+ bTagDao.update(accountId, context);
+
+ // Refresh fields
+ bFieldDao.update(accountId, context);
+
+ // Refresh BOS (bundles only for now)
+ bosDao.update(accountId, ObjectType.BUNDLE, context);
+
+ logService.log(LogService.LOG_INFO, "Finished rebuild of Analytics for account " + accountId);
+ }
+}