killbill-uncached

subscription: optimize API to get account entitlements Signed-off-by:

9/18/2013 6:50:11 PM

Details

diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/api/DefaultEntitlementApi.java b/entitlement/src/main/java/com/ning/billing/entitlement/api/DefaultEntitlementApi.java
index 814faa3..bb5dddd 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/api/DefaultEntitlementApi.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/api/DefaultEntitlementApi.java
@@ -18,6 +18,7 @@ package com.ning.billing.entitlement.api;
 
 import java.util.LinkedList;
 import java.util.List;
+import java.util.Map;
 import java.util.UUID;
 
 import javax.annotation.Nullable;
@@ -222,7 +223,7 @@ public class DefaultEntitlementApi implements EntitlementApi {
 
     @Override
     public List<Entitlement> getAllEntitlementsForAccountId(final UUID accountId, final TenantContext tenantContext) throws EntitlementApiException {
-        final InternalTenantContext context = internalCallContextFactory.createInternalTenantContext(tenantContext);
+        final InternalTenantContext context = internalCallContextFactory.createInternalTenantContext(accountId, tenantContext);
         final Account account;
         try {
             account = accountApi.getAccountById(accountId, context);
@@ -231,9 +232,10 @@ public class DefaultEntitlementApi implements EntitlementApi {
         }
 
         final List<SubscriptionBaseBundle> bundles = subscriptionInternalApi.getBundlesForAccount(accountId, context);
+        final Map<UUID, List<SubscriptionBase>> subscriptionsPerBundle = subscriptionInternalApi.getSubscriptionsForAccount(context);
         final List<Entitlement> result = new LinkedList<Entitlement>();
         for (final SubscriptionBaseBundle bundle : bundles) {
-            final List<Entitlement> entitlements = getAllEntitlementsForBundleId(bundle.getId(), bundle.getAccountId(), account.getTimeZone(), bundle.getExternalKey(), context);
+            final List<Entitlement> entitlements = getAllEntitlementsForBundleId(bundle.getAccountId(), account.getTimeZone(), bundle.getExternalKey(), subscriptionsPerBundle.get(bundle.getId()), context);
             result.addAll(entitlements);
         }
         return result;
@@ -241,6 +243,10 @@ public class DefaultEntitlementApi implements EntitlementApi {
 
     private List<Entitlement> getAllEntitlementsForBundleId(final UUID bundleId, final UUID accountId, final DateTimeZone accountTimeZone, final String externalKey, final InternalTenantContext context) throws EntitlementApiException {
         final List<SubscriptionBase> subscriptions = subscriptionInternalApi.getSubscriptionsForBundle(bundleId, context);
+        return getAllEntitlementsForBundleId(accountId, accountTimeZone, externalKey, subscriptions, context);
+    }
+
+    private List<Entitlement> getAllEntitlementsForBundleId(final UUID accountId, final DateTimeZone accountTimeZone, final String externalKey, final List<SubscriptionBase> subscriptions, final InternalTenantContext context) {
         final EntitlementApi thisEntitlementApi = this;
         return ImmutableList.<Entitlement>copyOf(Collections2.transform(subscriptions, new Function<SubscriptionBase, Entitlement>() {
             @Nullable
diff --git a/subscription/src/main/java/com/ning/billing/subscription/api/svcs/DefaultSubscriptionInternalApi.java b/subscription/src/main/java/com/ning/billing/subscription/api/svcs/DefaultSubscriptionInternalApi.java
index 89ed2a9..969bd76 100644
--- a/subscription/src/main/java/com/ning/billing/subscription/api/svcs/DefaultSubscriptionInternalApi.java
+++ b/subscription/src/main/java/com/ning/billing/subscription/api/svcs/DefaultSubscriptionInternalApi.java
@@ -16,8 +16,10 @@
 
 package com.ning.billing.subscription.api.svcs;
 
+import java.util.HashMap;
 import java.util.LinkedList;
 import java.util.List;
+import java.util.Map;
 import java.util.UUID;
 
 import javax.annotation.Nullable;
@@ -215,6 +217,16 @@ public class DefaultSubscriptionInternalApi extends SubscriptionApiBase implemen
     }
 
     @Override
+    public Map<UUID, List<SubscriptionBase>> getSubscriptionsForAccount(final InternalTenantContext context) {
+        final Map<UUID, List<SubscriptionBase>> internalSubscriptions = dao.getSubscriptionsForAccount(context);
+        final Map<UUID, List<SubscriptionBase>> result = new HashMap<UUID, List<SubscriptionBase>>();
+        for (final UUID bundleId : internalSubscriptions.keySet()) {
+            result.put(bundleId, createSubscriptionsForApiUse(internalSubscriptions.get(bundleId)));
+        }
+        return result;
+    }
+
+    @Override
     public SubscriptionBase getBaseSubscription(UUID bundleId,
                                                 InternalTenantContext context) throws SubscriptionBaseApiException {
         final SubscriptionBase result = dao.getBaseSubscription(bundleId, context);
diff --git a/subscription/src/main/java/com/ning/billing/subscription/engine/dao/DefaultSubscriptionDao.java b/subscription/src/main/java/com/ning/billing/subscription/engine/dao/DefaultSubscriptionDao.java
index decb58d..42a2521 100644
--- a/subscription/src/main/java/com/ning/billing/subscription/engine/dao/DefaultSubscriptionDao.java
+++ b/subscription/src/main/java/com/ning/billing/subscription/engine/dao/DefaultSubscriptionDao.java
@@ -251,6 +251,40 @@ public class DefaultSubscriptionDao implements SubscriptionDao {
         });
     }
 
+    @Override
+    public Map<UUID, List<SubscriptionBase>> getSubscriptionsForAccount(final InternalTenantContext context) {
+        final Map<UUID, List<SubscriptionBase>> subscriptionsFromAccountId = getSubscriptionsFromAccountId(context);
+
+        final Map<UUID, List<SubscriptionBase>> result = new HashMap<UUID, List<SubscriptionBase>>();
+        for (final UUID bundleId : subscriptionsFromAccountId.keySet()) {
+            result.put(bundleId, buildBundleSubscriptions(bundleId, subscriptionsFromAccountId.get(bundleId), context));
+        }
+        return result;
+    }
+
+    private Map<UUID, List<SubscriptionBase>> getSubscriptionsFromAccountId(final InternalTenantContext context) {
+        final List<SubscriptionBase> allSubscriptions = transactionalSqlDao.execute(new EntitySqlDaoTransactionWrapper<List<SubscriptionBase>>() {
+            @Override
+            public List<SubscriptionBase> inTransaction(final EntitySqlDaoWrapperFactory<EntitySqlDao> entitySqlDaoWrapperFactory) throws Exception {
+                final List<SubscriptionModelDao> models = entitySqlDaoWrapperFactory.become(SubscriptionSqlDao.class).getByAccountRecordId(context);
+                return new ArrayList<SubscriptionBase>(Collections2.transform(models, new Function<SubscriptionModelDao, SubscriptionBase>() {
+                    @Override
+                    public SubscriptionBase apply(final SubscriptionModelDao input) {
+                        return SubscriptionModelDao.toSubscription(input);
+                    }
+                }));
+            }
+        });
+
+        final Map<UUID, List<SubscriptionBase>> result = new HashMap<UUID, List<SubscriptionBase>>();
+        for (final SubscriptionBase subscriptionBase : allSubscriptions) {
+            if (result.get(subscriptionBase.getBundleId()) == null) {
+                result.put(subscriptionBase.getBundleId(), new LinkedList<SubscriptionBase>());
+            }
+            result.get(subscriptionBase.getBundleId()).add(subscriptionBase);
+        }
+        return result;
+    }
 
     @Override
     public List<SubscriptionBase> getSubscriptionsForAccountAndKey(final UUID accountId,
diff --git a/subscription/src/main/java/com/ning/billing/subscription/engine/dao/RepairSubscriptionDao.java b/subscription/src/main/java/com/ning/billing/subscription/engine/dao/RepairSubscriptionDao.java
index 63f1ff9..3bee1ea 100644
--- a/subscription/src/main/java/com/ning/billing/subscription/engine/dao/RepairSubscriptionDao.java
+++ b/subscription/src/main/java/com/ning/billing/subscription/engine/dao/RepairSubscriptionDao.java
@@ -280,6 +280,11 @@ public class RepairSubscriptionDao implements SubscriptionDao, RepairSubscriptio
     }
 
     @Override
+    public Map<UUID, List<SubscriptionBase>> getSubscriptionsForAccount(final InternalTenantContext context) {
+        throw new SubscriptionBaseError(NOT_IMPLEMENTED);
+    }
+
+    @Override
     public Map<UUID, List<SubscriptionBaseEvent>> getEventsForBundle(final UUID bundleId, final InternalTenantContext context) {
         throw new SubscriptionBaseError(NOT_IMPLEMENTED);
     }
diff --git a/subscription/src/main/java/com/ning/billing/subscription/engine/dao/SubscriptionDao.java b/subscription/src/main/java/com/ning/billing/subscription/engine/dao/SubscriptionDao.java
index 9fd0210..cd93a2e 100644
--- a/subscription/src/main/java/com/ning/billing/subscription/engine/dao/SubscriptionDao.java
+++ b/subscription/src/main/java/com/ning/billing/subscription/engine/dao/SubscriptionDao.java
@@ -55,6 +55,8 @@ public interface SubscriptionDao {
 
     public List<SubscriptionBase> getSubscriptions(UUID bundleId, InternalTenantContext context);
 
+    public Map<UUID, List<SubscriptionBase>> getSubscriptionsForAccount(InternalTenantContext context);
+
     public List<SubscriptionBase> getSubscriptionsForAccountAndKey(UUID accountId, String bundleKey, InternalTenantContext context);
 
     // Update
diff --git a/subscription/src/test/java/com/ning/billing/subscription/engine/dao/MockSubscriptionDaoMemory.java b/subscription/src/test/java/com/ning/billing/subscription/engine/dao/MockSubscriptionDaoMemory.java
index dc761f5..e4b2eeb 100644
--- a/subscription/src/test/java/com/ning/billing/subscription/engine/dao/MockSubscriptionDaoMemory.java
+++ b/subscription/src/test/java/com/ning/billing/subscription/engine/dao/MockSubscriptionDaoMemory.java
@@ -19,6 +19,7 @@ package com.ning.billing.subscription.engine.dao;
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
@@ -200,6 +201,18 @@ public class MockSubscriptionDaoMemory implements SubscriptionDao {
     }
 
     @Override
+    public Map<UUID, List<SubscriptionBase>> getSubscriptionsForAccount(final InternalTenantContext context) {
+        final Map<UUID, List<SubscriptionBase>> results = new HashMap<UUID, List<SubscriptionBase>>();
+        for (final SubscriptionBase cur : subscriptions) {
+            if (results.get(cur.getBundleId()) == null) {
+                results.put(cur.getBundleId(), new LinkedList<SubscriptionBase>());
+            }
+            results.get(cur.getBundleId()).add(buildSubscription((DefaultSubscriptionBase) cur, context));
+        }
+        return results;
+    }
+
+    @Override
     public List<SubscriptionBaseEvent> getEventsForSubscription(final UUID subscriptionId, final InternalTenantContext context) {
         synchronized (events) {
             final List<SubscriptionBaseEvent> results = new LinkedList<SubscriptionBaseEvent>();
diff --git a/util/src/main/java/com/ning/billing/util/svcapi/subscription/SubscriptionBaseInternalApi.java b/util/src/main/java/com/ning/billing/util/svcapi/subscription/SubscriptionBaseInternalApi.java
index 2a6baba..fc77037 100644
--- a/util/src/main/java/com/ning/billing/util/svcapi/subscription/SubscriptionBaseInternalApi.java
+++ b/util/src/main/java/com/ning/billing/util/svcapi/subscription/SubscriptionBaseInternalApi.java
@@ -17,6 +17,7 @@
 package com.ning.billing.util.svcapi.subscription;
 
 import java.util.List;
+import java.util.Map;
 import java.util.UUID;
 
 import javax.annotation.Nullable;
@@ -26,8 +27,8 @@ import org.joda.time.DateTime;
 import com.ning.billing.catalog.api.PlanPhaseSpecifier;
 import com.ning.billing.entitlement.api.EntitlementAOStatusDryRun;
 import com.ning.billing.subscription.api.SubscriptionBase;
-import com.ning.billing.subscription.api.user.SubscriptionBaseBundle;
 import com.ning.billing.subscription.api.user.SubscriptionBaseApiException;
+import com.ning.billing.subscription.api.user.SubscriptionBaseBundle;
 import com.ning.billing.util.callcontext.InternalCallContext;
 import com.ning.billing.util.callcontext.InternalTenantContext;
 import com.ning.billing.util.events.EffectiveSubscriptionInternalEvent;
@@ -36,7 +37,7 @@ import com.ning.billing.util.events.EffectiveSubscriptionInternalEvent;
 public interface SubscriptionBaseInternalApi {
 
     public SubscriptionBase createSubscription(final UUID bundleId, final PlanPhaseSpecifier spec, final DateTime requestedDateWithMs,
-                                           final InternalCallContext context) throws SubscriptionBaseApiException;
+                                               final InternalCallContext context) throws SubscriptionBaseApiException;
 
 
     public SubscriptionBaseBundle createBundleForAccount(final UUID accountId, final String bundleName, final InternalCallContext context)
@@ -53,6 +54,8 @@ public interface SubscriptionBaseInternalApi {
 
     public List<SubscriptionBase> getSubscriptionsForBundle(final UUID bundleId, final InternalTenantContext context);
 
+    public Map<UUID, List<SubscriptionBase>> getSubscriptionsForAccount(final InternalTenantContext context);
+
     public SubscriptionBase getBaseSubscription(final UUID bundleId, final InternalTenantContext context) throws SubscriptionBaseApiException;
 
     public SubscriptionBase getSubscriptionFromId(final UUID id, final InternalTenantContext context) throws SubscriptionBaseApiException;
@@ -70,5 +73,5 @@ public interface SubscriptionBaseInternalApi {
     public DateTime getNextBillingDate(final UUID accountId, final InternalTenantContext context);
 
     public List<EntitlementAOStatusDryRun> getDryRunChangePlanStatus(final UUID subscriptionId, @Nullable final String baseProductName,
-                                                                   final DateTime requestedDate, final InternalTenantContext context) throws SubscriptionBaseApiException;
+                                                                     final DateTime requestedDate, final InternalTenantContext context) throws SubscriptionBaseApiException;
 }