killbill-memoizeit

Add implementation for new Api getSubscriptionBundlesForExternalKey Add

9/24/2013 5:36:18 PM

Details

diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/api/DefaultSubscriptionApi.java b/entitlement/src/main/java/com/ning/billing/entitlement/api/DefaultSubscriptionApi.java
index e599a4f..34ddd2b 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/api/DefaultSubscriptionApi.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/api/DefaultSubscriptionApi.java
@@ -24,7 +24,6 @@ import java.util.List;
 import java.util.Set;
 import java.util.UUID;
 
-import javax.annotation.Nullable;
 import javax.inject.Inject;
 
 import org.joda.time.DateTimeZone;
@@ -46,7 +45,6 @@ import com.ning.billing.util.svcapi.subscription.SubscriptionBaseInternalApi;
 import com.google.common.base.Function;
 import com.google.common.base.Predicate;
 import com.google.common.collect.Collections2;
-import com.google.common.collect.Iterables;
 import com.google.common.collect.LinkedListMultimap;
 import com.google.common.collect.ListMultimap;
 
@@ -153,6 +151,28 @@ public class DefaultSubscriptionApi implements SubscriptionApi {
     }
 
     @Override
+    public List<SubscriptionBundle> getSubscriptionBundlesForExternalKey(final String externalKey, final TenantContext context) throws SubscriptionApiException {
+
+        final InternalTenantContext internalContext = internalCallContextFactory.createInternalTenantContext(context);
+        try {
+            final List<SubscriptionBaseBundle> baseBundles = subscriptionInternalApi.getBundlesForKey(externalKey, internalContext);
+            final List<SubscriptionBundle> result = new ArrayList<SubscriptionBundle>(baseBundles.size());
+            for (SubscriptionBaseBundle cur : baseBundles) {
+                final List<Entitlement> allEntitlementsForBundle = entitlementApi.getAllEntitlementsForBundle(cur.getId(), context);
+                final SubscriptionBundle bundle = getSubscriptionBundleFromEntitlements(cur.getId(), allEntitlementsForBundle, context);
+                result.add(bundle);
+            }
+            return result;
+        } catch (SubscriptionBaseApiException e) {
+            throw new SubscriptionApiException(e);
+        } catch (EntitlementApiException e) {
+            throw new SubscriptionApiException(e);
+        } catch (AccountApiException e) {
+            throw new SubscriptionApiException(e);
+        }
+    }
+
+    @Override
     public List<SubscriptionBundle> getSubscriptionBundlesForAccountId(final UUID accountId,
                                                                        final TenantContext context) throws SubscriptionApiException {
         try {
@@ -161,19 +181,7 @@ public class DefaultSubscriptionApi implements SubscriptionApi {
             if (entitlements.isEmpty()) {
                 return Collections.emptyList();
             }
-
-            final ListMultimap<UUID, Entitlement> perBundleEntitlements = LinkedListMultimap.create();
-            for (Entitlement cur : entitlements) {
-                perBundleEntitlements.put(cur.getBundleId(), cur);
-            }
-
-            final List<SubscriptionBundle> result = new ArrayList<SubscriptionBundle>(perBundleEntitlements.keySet().size());
-            for (UUID bundleId : perBundleEntitlements.keySet()) {
-                final List<Entitlement> e = perBundleEntitlements.get(bundleId);
-                final SubscriptionBundle b = getSubscriptionBundleFromEntitlements(bundleId, e, context);
-                result.add(b);
-            }
-            return result;
+            return getSubscriptionBundles(entitlements, context);
         } catch (EntitlementApiException e) {
             throw new SubscriptionApiException(e);
         } catch (SubscriptionBaseApiException e) {
@@ -183,6 +191,21 @@ public class DefaultSubscriptionApi implements SubscriptionApi {
         }
     }
 
+    private List<SubscriptionBundle> getSubscriptionBundles(final List<Entitlement> entitlements, final TenantContext context) throws SubscriptionBaseApiException, AccountApiException {
+        final ListMultimap<UUID, Entitlement> perBundleEntitlements = LinkedListMultimap.create();
+        for (Entitlement cur : entitlements) {
+            perBundleEntitlements.put(cur.getBundleId(), cur);
+        }
+
+        final List<SubscriptionBundle> result = new ArrayList<SubscriptionBundle>(perBundleEntitlements.keySet().size());
+        for (UUID bundleId : perBundleEntitlements.keySet()) {
+            final List<Entitlement> allEntitlementsForBundle = perBundleEntitlements.get(bundleId);
+            final SubscriptionBundle bundle = getSubscriptionBundleFromEntitlements(bundleId, allEntitlementsForBundle, context);
+            result.add(bundle);
+        }
+        return result;
+    }
+
     private Subscription fromEntitlement(final Entitlement entitlement, final InternalTenantContext internalTenantContext) {
 
         final List<BlockingState> states = blockingStateDao.getBlockingState(entitlement.getId(), internalTenantContext);
@@ -225,7 +248,7 @@ public class DefaultSubscriptionApi implements SubscriptionApi {
         }));
 
         final SubscriptionBundleTimeline timeline = new DefaultSubscriptionBundleTimeline(accountTimeZone, account.getId(), bundleId, baseBundle.getExternalKey(), entitlements, filteredBlockingStates);
-        final DefaultSubscriptionBundle bundle = new DefaultSubscriptionBundle(bundleId, baseBundle.getAccountId(), baseBundle.getExternalKey(), subscriptions, timeline, baseBundle.getCreatedDate(), baseBundle.getUpdatedDate());
+        final DefaultSubscriptionBundle bundle = new DefaultSubscriptionBundle(bundleId, baseBundle.getAccountId(), baseBundle.getExternalKey(), subscriptions, timeline, baseBundle.getOriginalCreatedDate() , baseBundle.getCreatedDate(), baseBundle.getUpdatedDate());
         return bundle;
     }
 }
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/api/DefaultSubscriptionBundle.java b/entitlement/src/main/java/com/ning/billing/entitlement/api/DefaultSubscriptionBundle.java
index 8cd38f9..a75713e 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/api/DefaultSubscriptionBundle.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/api/DefaultSubscriptionBundle.java
@@ -30,13 +30,16 @@ public class DefaultSubscriptionBundle implements SubscriptionBundle {
     private final SubscriptionBundleTimeline bundleTimeline;
     private final DateTime createdDate;
     private final DateTime updatedDate;
+    private final DateTime originalCreatedDate;
 
-    public DefaultSubscriptionBundle(final UUID id, final UUID accountId, final String externalKey, final List<Subscription> subscriptions, final SubscriptionBundleTimeline bundleTimeline, final DateTime createdDate, final DateTime updatedDate) {
+    public DefaultSubscriptionBundle(final UUID id, final UUID accountId, final String externalKey, final List<Subscription> subscriptions, final SubscriptionBundleTimeline bundleTimeline,
+                                     final DateTime originalCreatedDate, final DateTime createdDate, final DateTime updatedDate) {
         this.id = id;
         this.accountId = accountId;
         this.externalKey = externalKey;
         this.subscriptions = subscriptions;
         this.bundleTimeline = bundleTimeline;
+        this.originalCreatedDate = originalCreatedDate;
         this.createdDate = createdDate;
         this.updatedDate = updatedDate;
     }
@@ -52,6 +55,11 @@ public class DefaultSubscriptionBundle implements SubscriptionBundle {
     }
 
     @Override
+    public DateTime getOriginalCreatedDate() {
+        return originalCreatedDate;
+    }
+
+    @Override
     public List<Subscription> getSubscriptions() {
         return subscriptions;
     }
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/TestDefaultSubscriptionApi.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/TestDefaultSubscriptionApi.java
new file mode 100644
index 0000000..6af89f5
--- /dev/null
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/TestDefaultSubscriptionApi.java
@@ -0,0 +1,120 @@
+package com.ning.billing.entitlement.api;
+
+import java.util.List;
+
+import org.joda.time.LocalDate;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import com.ning.billing.account.api.Account;
+import com.ning.billing.account.api.AccountApiException;
+import com.ning.billing.catalog.api.BillingPeriod;
+import com.ning.billing.catalog.api.PlanPhaseSpecifier;
+import com.ning.billing.catalog.api.PriceListSet;
+import com.ning.billing.catalog.api.ProductCategory;
+import com.ning.billing.entitlement.EntitlementTestSuiteWithEmbeddedDB;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNull;
+
+public class TestDefaultSubscriptionApi extends EntitlementTestSuiteWithEmbeddedDB {
+
+
+    @Test(groups = "slow")
+    public void testWithMultipleBundle() {
+
+        try {
+
+
+            final String externalKey = "fooXXX";
+
+            final LocalDate initialDate = new LocalDate(2013, 8, 7);
+            clock.setDay(initialDate);
+
+            final Account account = accountApi.createAccount(getAccountData(7), callContext);
+
+            final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Shotgun", ProductCategory.BASE, BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null);
+
+            // Create entitlement and check each field
+            final Entitlement entitlement = entitlementApi.createBaseEntitlement(account.getId(), spec, externalKey, initialDate, callContext);
+            assertEquals(entitlement.getAccountId(), account.getId());
+            assertEquals(entitlement.getExternalKey(), externalKey);
+
+            assertEquals(entitlement.getEffectiveStartDate(), initialDate);
+            assertNull(entitlement.getEffectiveEndDate());
+
+            final List<SubscriptionBundle> bundles = subscriptionApi.getSubscriptionBundlesForExternalKey(externalKey, callContext);
+            assertEquals(bundles.size(), 1);
+
+            // Cancel entitlement
+            clock.addDays(3);
+            entitlement.cancelEntitlementWithDate(new LocalDate(clock.getUTCNow(), account.getTimeZone()), true, callContext);
+
+            clock.addDays(1);
+            // Re-create a new bundle with same externalKey
+            final PlanPhaseSpecifier spec2 = new PlanPhaseSpecifier("Pistol", ProductCategory.BASE, BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null);
+
+            // Create entitlement and check each field
+            final Entitlement entitlement2 = entitlementApi.createBaseEntitlement(account.getId(), spec2, externalKey, new LocalDate(clock.getUTCNow(), account.getTimeZone()), callContext);
+            assertEquals(entitlement2.getAccountId(), account.getId());
+            assertEquals(entitlement2.getExternalKey(), externalKey);
+
+            final List<SubscriptionBundle> bundles2 = subscriptionApi.getSubscriptionBundlesForExternalKey(externalKey, callContext);
+            assertEquals(bundles2.size(), 2);
+
+            SubscriptionBundle firstbundle = bundles2.get(0);
+            assertEquals(firstbundle.getSubscriptions().size(), 1);
+            assertEquals(firstbundle.getSubscriptions().get(0).getEffectiveStartDate(), new LocalDate(2013, 8, 7));
+            assertEquals(firstbundle.getSubscriptions().get(0).getBillingStartDate(), new LocalDate(2013, 8, 7));
+            assertEquals(firstbundle.getSubscriptions().get(0).getEffectiveEndDate(), new LocalDate(2013, 8, 10));
+            assertEquals(firstbundle.getSubscriptions().get(0).getBillingEndDate(), new LocalDate(2013, 8, 10));
+
+            SubscriptionBundle secondbundle = bundles2.get(1);
+            assertEquals(secondbundle.getSubscriptions().size(), 1);
+            assertEquals(secondbundle.getSubscriptions().get(0).getEffectiveStartDate(), new LocalDate(2013, 8, 11));
+            assertEquals(secondbundle.getSubscriptions().get(0).getBillingStartDate(), new LocalDate(2013, 8, 11));
+            assertNull(secondbundle.getSubscriptions().get(0).getEffectiveEndDate());
+            assertNull(secondbundle.getSubscriptions().get(0).getBillingEndDate());
+            assertEquals(secondbundle.getOriginalCreatedDate().compareTo(firstbundle.getCreatedDate()), 0);
+
+
+            clock.addDays(3);
+            final Account account2 = accountApi.createAccount(getAccountData(7), callContext);
+
+            entitlementApi.transferEntitlements(account.getId(), account2.getId(), externalKey, new LocalDate(clock.getUTCNow(), account.getTimeZone()), callContext);
+
+            final List<SubscriptionBundle> bundles3 = subscriptionApi.getSubscriptionBundlesForExternalKey(externalKey, callContext);
+            assertEquals(bundles3.size(), 3);
+
+            firstbundle = bundles3.get(0);
+            assertEquals(firstbundle.getSubscriptions().size(), 1);
+            assertEquals(firstbundle.getSubscriptions().get(0).getEffectiveStartDate(), new LocalDate(2013, 8, 7));
+            assertEquals(firstbundle.getSubscriptions().get(0).getBillingStartDate(), new LocalDate(2013, 8, 7));
+            assertEquals(firstbundle.getSubscriptions().get(0).getEffectiveEndDate(), new LocalDate(2013, 8, 10));
+            assertEquals(firstbundle.getSubscriptions().get(0).getBillingEndDate(), new LocalDate(2013, 8, 10));
+
+            secondbundle = bundles3.get(1);
+            assertEquals(secondbundle.getSubscriptions().size(), 1);
+            assertEquals(secondbundle.getSubscriptions().get(0).getEffectiveStartDate(), new LocalDate(2013, 8, 11));
+            assertEquals(secondbundle.getSubscriptions().get(0).getBillingStartDate(), new LocalDate(2013, 8, 11));
+            assertEquals(secondbundle.getSubscriptions().get(0).getEffectiveEndDate(), new LocalDate(2013, 8, 14));
+            assertEquals(secondbundle.getSubscriptions().get(0).getBillingEndDate(), new LocalDate(2013, 8, 14));
+            assertEquals(secondbundle.getOriginalCreatedDate().compareTo(firstbundle.getCreatedDate()), 0);
+
+            SubscriptionBundle thirdBundle = bundles3.get(2);
+            assertEquals(thirdBundle.getSubscriptions().size(), 1);
+            assertEquals(thirdBundle.getSubscriptions().get(0).getEffectiveStartDate(), new LocalDate(2013, 8, 14));
+            assertEquals(thirdBundle.getSubscriptions().get(0).getBillingStartDate(), new LocalDate(2013, 8, 14));
+            assertNull(thirdBundle.getSubscriptions().get(0).getEffectiveEndDate());
+            assertNull(thirdBundle.getSubscriptions().get(0).getBillingEndDate());
+            assertEquals(thirdBundle.getOriginalCreatedDate().compareTo(firstbundle.getCreatedDate()), 0);
+
+        } catch (EntitlementApiException e) {
+            Assert.fail("Test failed " + e.getMessage());
+        } catch (AccountApiException e) {
+            Assert.fail("Test failed " + e.getMessage());
+        } catch (SubscriptionApiException e) {
+            Assert.fail("Test failed " + e.getMessage());
+        }
+    }
+}
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/EntitlementTestSuiteWithEmbeddedDB.java b/entitlement/src/test/java/com/ning/billing/entitlement/EntitlementTestSuiteWithEmbeddedDB.java
index 5691cc9..2b2f308 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/EntitlementTestSuiteWithEmbeddedDB.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/EntitlementTestSuiteWithEmbeddedDB.java
@@ -40,6 +40,7 @@ import com.ning.billing.catalog.api.CatalogService;
 import com.ning.billing.catalog.api.Currency;
 import com.ning.billing.clock.ClockMock;
 import com.ning.billing.entitlement.api.EntitlementApi;
+import com.ning.billing.entitlement.api.SubscriptionApi;
 import com.ning.billing.entitlement.dao.BlockingStateDao;
 import com.ning.billing.entitlement.glue.TestEntitlementModuleWithEmbeddedDB;
 import com.ning.billing.mock.MockAccountBuilder;
@@ -72,6 +73,8 @@ public class EntitlementTestSuiteWithEmbeddedDB extends GuicyKillbillTestSuiteWi
     @Inject
     protected EntitlementApi entitlementApi;
     @Inject
+    protected SubscriptionApi subscriptionApi;
+    @Inject
     protected BlockingStateDao blockingStateDao;
     @Inject
     protected CatalogService catalogService;