killbill-uncached

Add new internal subscription API to retrieve active bundle

9/6/2013 10:57:18 PM

Details

pom.xml 2(+1 -1)

diff --git a/pom.xml b/pom.xml
index ba91b1b..3a16c46 100644
--- a/pom.xml
+++ b/pom.xml
@@ -19,7 +19,7 @@
     <parent>
         <artifactId>killbill-oss-parent</artifactId>
         <groupId>com.ning.billing</groupId>
-        <version>0.4.4</version>
+        <version>0.4.5</version>
     </parent>
     <artifactId>killbill</artifactId>
     <version>0.6.6-SNAPSHOT</version>
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 824f22e..89ed2a9 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
@@ -152,8 +152,12 @@ public class DefaultSubscriptionInternalApi extends SubscriptionApiBase implemen
     }
 
     @Override
-    public SubscriptionBaseBundle createBundleForAccount(final UUID accountId, final String bundleName, final InternalCallContext context) throws SubscriptionBaseApiException {
-        final DefaultSubscriptionBaseBundle bundle = new DefaultSubscriptionBaseBundle(bundleName, accountId, clock.getUTCNow());
+    public SubscriptionBaseBundle createBundleForAccount(final UUID accountId, final String bundleKey, final InternalCallContext context) throws SubscriptionBaseApiException {
+        final SubscriptionBaseBundle result = getActiveBundleForKeyNotException(bundleKey, context);
+        if (result != null) {
+            throw new SubscriptionBaseApiException(ErrorCode.SUB_CREATE_ACTIVE_BUNDLE_KEY_EXISTS, bundleKey);
+        }
+        final DefaultSubscriptionBaseBundle bundle = new DefaultSubscriptionBaseBundle(bundleKey, accountId, clock.getUTCNow());
         return dao.createSubscriptionBundle(bundle, context);
     }
 
@@ -178,6 +182,32 @@ public class DefaultSubscriptionInternalApi extends SubscriptionApiBase implemen
     }
 
     @Override
+    public SubscriptionBaseBundle getActiveBundleForKey(final String bundleKey, final InternalTenantContext context) throws SubscriptionBaseApiException  {
+        final SubscriptionBaseBundle result =  getActiveBundleForKeyNotException(bundleKey, context);
+        if (result == null) {
+            throw new SubscriptionBaseApiException(ErrorCode.SUB_GET_INVALID_BUNDLE_KEY, bundleKey);
+        }
+        return result;
+    }
+
+    private SubscriptionBaseBundle getActiveBundleForKeyNotException(final String bundleKey, final InternalTenantContext context)  {
+
+        final List<SubscriptionBaseBundle> existingBundles = dao.getSubscriptionBundlesForKey(bundleKey, context);
+        for (SubscriptionBaseBundle cur : existingBundles) {
+            final List<SubscriptionBase> subscriptions = dao.getSubscriptions(cur.getId(), context);
+            for (SubscriptionBase s : subscriptions) {
+                if (s.getCategory() == ProductCategory.ADD_ON) {
+                    continue;
+                }
+                if (s.getEndDate() == null || s.getEndDate().compareTo(clock.getUTCNow()) > 0) {
+                    return cur;
+                }
+            }
+        }
+        return null;
+    }
+
+    @Override
     public List<SubscriptionBase> getSubscriptionsForBundle(UUID bundleId,
                                                             InternalTenantContext context) {
         final List<SubscriptionBase> internalSubscriptions = dao.getSubscriptions(bundleId, context);
diff --git a/subscription/src/test/java/com/ning/billing/subscription/api/user/TestUserApiCreate.java b/subscription/src/test/java/com/ning/billing/subscription/api/user/TestUserApiCreate.java
index 9a35808..293fa20 100644
--- a/subscription/src/test/java/com/ning/billing/subscription/api/user/TestUserApiCreate.java
+++ b/subscription/src/test/java/com/ning/billing/subscription/api/user/TestUserApiCreate.java
@@ -25,6 +25,7 @@ import org.slf4j.LoggerFactory;
 import org.testng.Assert;
 import org.testng.annotations.Test;
 
+import com.ning.billing.ErrorCode;
 import com.ning.billing.api.TestApiListener.NextEvent;
 import com.ning.billing.catalog.api.BillingPeriod;
 import com.ning.billing.catalog.api.PhaseType;
@@ -32,6 +33,7 @@ import com.ning.billing.catalog.api.Plan;
 import com.ning.billing.catalog.api.PlanPhase;
 import com.ning.billing.catalog.api.PriceListSet;
 import com.ning.billing.catalog.api.ProductCategory;
+import com.ning.billing.subscription.DefaultSubscriptionTestInitializer;
 import com.ning.billing.subscription.SubscriptionTestSuiteWithEmbeddedDB;
 import com.ning.billing.subscription.events.SubscriptionBaseEvent;
 import com.ning.billing.subscription.events.phase.PhaseEvent;
@@ -44,6 +46,45 @@ public class TestUserApiCreate extends SubscriptionTestSuiteWithEmbeddedDB {
 
     private static final Logger log = LoggerFactory.getLogger(TestUserApiCreate.class);
 
+
+    @Test(groups = "slow")
+    public void testCreateBundlesWithSameExternalKeys() {
+        try {
+            final DateTime init = clock.getUTCNow();
+            final DateTime requestedDate = init.minusYears(1);
+
+            final String productName = "Shotgun";
+            final BillingPeriod term = BillingPeriod.MONTHLY;
+            final String planSetName = PriceListSet.DEFAULT_PRICELIST_NAME;
+
+
+            final DefaultSubscriptionBase subscription = (DefaultSubscriptionBase) subscriptionInternalApi.createSubscription(bundle.getId(),
+                                                                                                                              testUtil.getProductSpecifier(productName, planSetName, term, null), requestedDate, internalCallContext);
+            assertNotNull(subscription);
+
+            try {
+                final SubscriptionBaseBundle newBundle = subscriptionInternalApi.createBundleForAccount(bundle.getAccountId(), DefaultSubscriptionTestInitializer.DEFAULT_BUNDLE_KEY, internalCallContext);
+                Assert.fail("Unexpected success to create a bundle");
+            } catch (SubscriptionBaseApiException e) {
+                Assert.assertEquals(e.getCode(), ErrorCode.SUB_CREATE_ACTIVE_BUNDLE_KEY_EXISTS.getCode());
+            }
+
+            subscription.cancel(clock.getUTCNow(), callContext);
+
+            final SubscriptionBaseBundle newBundle = subscriptionInternalApi.createBundleForAccount(bundle.getAccountId(), DefaultSubscriptionTestInitializer.DEFAULT_BUNDLE_KEY, internalCallContext);
+            assertNotNull(newBundle);
+
+            final DefaultSubscriptionBase newSubscription = (DefaultSubscriptionBase) subscriptionInternalApi.createSubscription(newBundle.getId(),
+                                                                                                                              testUtil.getProductSpecifier(productName, planSetName, term, null), requestedDate, internalCallContext);
+            assertNotNull(newSubscription);
+
+
+        } catch (SubscriptionBaseApiException e) {
+            log.error("Unexpected exception", e);
+            Assert.fail(e.getMessage());
+        }
+    }
+
     @Test(groups = "slow")
     public void testCreateWithRequestedDate() {
         try {
@@ -58,7 +99,7 @@ public class TestUserApiCreate extends SubscriptionTestSuiteWithEmbeddedDB {
             testListener.pushExpectedEvent(NextEvent.CREATE);
 
             final DefaultSubscriptionBase subscription = (DefaultSubscriptionBase) subscriptionInternalApi.createSubscription(bundle.getId(),
-                                                                                                       testUtil.getProductSpecifier(productName, planSetName, term, null), requestedDate, internalCallContext);
+                                                                                                                              testUtil.getProductSpecifier(productName, planSetName, term, null), requestedDate, internalCallContext);
             assertNotNull(subscription);
 
             //
@@ -106,7 +147,7 @@ public class TestUserApiCreate extends SubscriptionTestSuiteWithEmbeddedDB {
             testListener.pushExpectedEvent(NextEvent.CREATE);
 
             final DefaultSubscriptionBase subscription = (DefaultSubscriptionBase) subscriptionInternalApi.createSubscription(bundle.getId(),
-                                                                                                       testUtil.getProductSpecifier(productName, planSetName, term, PhaseType.EVERGREEN), clock.getUTCNow(), internalCallContext);
+                                                                                                                              testUtil.getProductSpecifier(productName, planSetName, term, PhaseType.EVERGREEN), clock.getUTCNow(), internalCallContext);
             assertNotNull(subscription);
 
             assertEquals(subscription.getActiveVersion(), SubscriptionEvents.INITIAL_VERSION);
@@ -144,8 +185,8 @@ public class TestUserApiCreate extends SubscriptionTestSuiteWithEmbeddedDB {
             testListener.pushExpectedEvent(NextEvent.CREATE);
 
             final DefaultSubscriptionBase subscription = (DefaultSubscriptionBase) subscriptionInternalApi.createSubscription(bundle.getId(),
-                                                                                                       testUtil.getProductSpecifier(productName, planSetName, term, null),
-                                                                                                       clock.getUTCNow(), internalCallContext);
+                                                                                                                              testUtil.getProductSpecifier(productName, planSetName, term, null),
+                                                                                                                              clock.getUTCNow(), internalCallContext);
             assertNotNull(subscription);
 
             assertEquals(subscription.getActiveVersion(), SubscriptionEvents.INITIAL_VERSION);
@@ -200,7 +241,7 @@ public class TestUserApiCreate extends SubscriptionTestSuiteWithEmbeddedDB {
 
             // CREATE SUBSCRIPTION
             DefaultSubscriptionBase subscription = (DefaultSubscriptionBase) subscriptionInternalApi.createSubscription(bundle.getId(),
-                                                                                                 testUtil.getProductSpecifier(productName, planSetName, term, null), clock.getUTCNow(), internalCallContext);
+                                                                                                                        testUtil.getProductSpecifier(productName, planSetName, term, null), clock.getUTCNow(), internalCallContext);
             assertNotNull(subscription);
 
             PlanPhase currentPhase = subscription.getCurrentPhase();
@@ -244,7 +285,7 @@ public class TestUserApiCreate extends SubscriptionTestSuiteWithEmbeddedDB {
             testListener.pushExpectedEvent(NextEvent.CREATE);
 
             final DefaultSubscriptionBase subscription = (DefaultSubscriptionBase) subscriptionInternalApi.createSubscription(bundle.getId(),
-                                                                                                       testUtil.getProductSpecifier(productName, planSetName, term, null), clock.getUTCNow(), internalCallContext);
+                                                                                                                              testUtil.getProductSpecifier(productName, planSetName, term, null), clock.getUTCNow(), internalCallContext);
             assertNotNull(subscription);
 
             assertListenerStatus();
diff --git a/subscription/src/test/java/com/ning/billing/subscription/DefaultSubscriptionTestInitializer.java b/subscription/src/test/java/com/ning/billing/subscription/DefaultSubscriptionTestInitializer.java
index 058a22d..bab5ea7 100644
--- a/subscription/src/test/java/com/ning/billing/subscription/DefaultSubscriptionTestInitializer.java
+++ b/subscription/src/test/java/com/ning/billing/subscription/DefaultSubscriptionTestInitializer.java
@@ -43,6 +43,7 @@ import static org.testng.Assert.assertNotNull;
 
 public class DefaultSubscriptionTestInitializer implements SubscriptionTestInitializer {
 
+    public static final String DEFAULT_BUNDLE_KEY = "myDefaultBundle";
 
     protected static final Logger log = LoggerFactory.getLogger(DefaultSubscriptionTestInitializer.class);
 
@@ -78,7 +79,7 @@ public class DefaultSubscriptionTestInitializer implements SubscriptionTestIniti
 
     public SubscriptionBaseBundle initBundle(final SubscriptionBaseInternalApi subscriptionApi, final InternalCallContext callContext) throws Exception {
         final UUID accountId = UUID.randomUUID();
-        final SubscriptionBaseBundle bundle = subscriptionApi.createBundleForAccount(accountId, "myDefaultBundle",  callContext);
+        final SubscriptionBaseBundle bundle = subscriptionApi.createBundleForAccount(accountId, DEFAULT_BUNDLE_KEY,  callContext);
         assertNotNull(bundle);
         return bundle;
     }