killbill-aplcache

Merge branch 'integration' of github.com:ning/killbill

7/5/2012 5:18:16 PM

Details

diff --git a/api/src/main/java/com/ning/billing/entitlement/api/user/Subscription.java b/api/src/main/java/com/ning/billing/entitlement/api/user/Subscription.java
index e75ea1b..cb8993d 100644
--- a/api/src/main/java/com/ning/billing/entitlement/api/user/Subscription.java
+++ b/api/src/main/java/com/ning/billing/entitlement/api/user/Subscription.java
@@ -58,6 +58,8 @@ public interface Subscription extends Entity, Blockable {
 
     public DateTime getEndDate();
 
+    public DateTime getFutureEndDate();
+
     public Plan getCurrentPlan();
 
     public PriceList getCurrentPriceList();
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionData.java b/entitlement/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionData.java
index d5586e9..58fe83c 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionData.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionData.java
@@ -146,6 +146,24 @@ public class SubscriptionData extends EntityBase implements Subscription {
     }
 
     @Override
+    public DateTime getFutureEndDate() {
+        if (transitions == null) {
+            return null;
+        }
+        final SubscriptionTransitionDataIterator it = new SubscriptionTransitionDataIterator(
+                clock, transitions, Order.ASC_FROM_PAST, Kind.ENTITLEMENT,
+                Visibility.ALL, TimeLimit.FUTURE_ONLY);
+        while (it.hasNext()) {
+            final SubscriptionTransitionData cur = it.next();
+            if (cur.getTransitionType() == SubscriptionTransitionType.CANCEL) {
+                return cur.getEffectiveTransitionTime();
+            }
+        }
+        return null;
+    }
+
+
+    @Override
     public boolean cancel(final DateTime requestedDate, final boolean eot,
                           final CallContext context) throws EntitlementUserApiException {
         return apiService.cancel(this, requestedDate, eot, context);
@@ -264,6 +282,7 @@ public class SubscriptionData extends EntityBase implements Subscription {
         return true;
     }
 
+    @Override
     public List<EffectiveSubscriptionEvent> getBillingTransitions() {
 
         if (transitions == null) {
@@ -343,20 +362,9 @@ public class SubscriptionData extends EntityBase implements Subscription {
         throw new EntitlementError(String.format("Failed to find InitialTransitionForCurrentPlan id = %s", getId()));
     }
 
+
     public boolean isSubscriptionFutureCancelled() {
-        if (transitions == null) {
-            return false;
-        }
-        final SubscriptionTransitionDataIterator it = new SubscriptionTransitionDataIterator(
-                clock, transitions, Order.ASC_FROM_PAST, Kind.ENTITLEMENT,
-                Visibility.ALL, TimeLimit.FUTURE_ONLY);
-        while (it.hasNext()) {
-            final SubscriptionTransitionData cur = it.next();
-            if (cur.getTransitionType() == SubscriptionTransitionType.CANCEL) {
-                return true;
-            }
-        }
-        return false;
+        return getFutureEndDate() != null;
     }
 
     public DateTime getPlanChangeEffectiveDate(final ActionPolicy policy,
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCancel.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCancel.java
index afebb34..879bb90 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCancel.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCancel.java
@@ -117,6 +117,9 @@ public abstract class TestUserApiCancel extends TestApiBase {
             assertFalse(testListener.isCompleted(3000));
             testListener.reset();
 
+            DateTime futureEndDate = subscription.getFutureEndDate();
+            Assert.assertNotNull(futureEndDate);
+
             // MOVE TO EOT + RECHECK
             testListener.pushExpectedEvent(NextEvent.CANCEL);
             it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusMonths(1));
@@ -124,6 +127,8 @@ public abstract class TestUserApiCancel extends TestApiBase {
             final DateTime future = clock.getUTCNow();
             assertTrue(testListener.isCompleted(5000));
 
+            assertTrue(futureEndDate.compareTo(subscription.getEndDate()) == 0);
+
             final PlanPhase currentPhase = subscription.getCurrentPhase();
             assertNull(currentPhase);
             checkNextPhaseChange(subscription, 0, null);
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/SubscriptionJsonNoEvents.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/SubscriptionJsonNoEvents.java
index 3c7b2f6..988daed 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/SubscriptionJsonNoEvents.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/SubscriptionJsonNoEvents.java
@@ -39,6 +39,8 @@ public class SubscriptionJsonNoEvents extends SubscriptionJsonSimple {
 
     private final DateTime chargedThroughDate;
 
+    private final DateTime cancelledDate;
+
     @JsonCreator
     public SubscriptionJsonNoEvents(@JsonProperty("subscriptionId") @Nullable final String subscriptionId,
                                     @JsonProperty("bundleId") @Nullable final String bundleId,
@@ -47,7 +49,8 @@ public class SubscriptionJsonNoEvents extends SubscriptionJsonSimple {
                                     @JsonProperty("productCategory") @Nullable final String productCategory,
                                     @JsonProperty("billingPeriod") @Nullable final String billingPeriod,
                                     @JsonProperty("priceList") @Nullable final String priceList,
-                                    @JsonProperty("chargedThroughDate") @Nullable final DateTime chargedThroughDate) {
+                                    @JsonProperty("chargedThroughDate") @Nullable final DateTime chargedThroughDate,
+                                    @JsonProperty("cancelledDate") @Nullable final DateTime cancelledDate) {
         super(subscriptionId);
         this.bundleId = bundleId;
         this.startDate = startDate;
@@ -56,18 +59,21 @@ public class SubscriptionJsonNoEvents extends SubscriptionJsonSimple {
         this.billingPeriod = billingPeriod;
         this.priceList = priceList;
         this.chargedThroughDate = chargedThroughDate;
+        this.cancelledDate = cancelledDate;
     }
 
     public SubscriptionJsonNoEvents() {
-        this(null, null, null, null, null, null, null, null);
+        this(null, null, null, null, null, null, null, null, null);
     }
 
     public SubscriptionJsonNoEvents(final Subscription data) {
         this(data.getId().toString(), data.getBundleId().toString(), data.getStartDate(), data.getCurrentPlan().getProduct().getName(),
              data.getCurrentPlan().getProduct().getCategory().toString(), data.getCurrentPlan().getBillingPeriod().toString(),
-             data.getCurrentPriceList().getName(), data.getChargedThroughDate());
+             data.getCurrentPriceList().getName(), data.getChargedThroughDate(),
+             data.getEndDate() != null ? data.getEndDate() : data.getFutureEndDate());
     }
 
+    @Override
     public String getSubscriptionId() {
         return subscriptionId;
     }
@@ -100,6 +106,10 @@ public class SubscriptionJsonNoEvents extends SubscriptionJsonSimple {
         return chargedThroughDate;
     }
 
+    public DateTime getCancelledDate() {
+        return cancelledDate;
+    }
+
     @Override
     public String toString() {
         return "SubscriptionJson [subscriptionId=" + subscriptionId
diff --git a/jaxrs/src/test/java/com/ning/billing/jaxrs/json/TestSubscriptionJsonNoEvents.java b/jaxrs/src/test/java/com/ning/billing/jaxrs/json/TestSubscriptionJsonNoEvents.java
index 42d0794..c663b30 100644
--- a/jaxrs/src/test/java/com/ning/billing/jaxrs/json/TestSubscriptionJsonNoEvents.java
+++ b/jaxrs/src/test/java/com/ning/billing/jaxrs/json/TestSubscriptionJsonNoEvents.java
@@ -54,9 +54,11 @@ public class TestSubscriptionJsonNoEvents {
         final String billingPeriod = UUID.randomUUID().toString();
         final String priceList = UUID.randomUUID().toString();
         final DateTime chargedThroughDate = new DateTime(DateTimeZone.UTC);
+        final DateTime endDate = new DateTime(DateTimeZone.UTC);
+
         final SubscriptionJsonNoEvents subscriptionJsonNoEvents = new SubscriptionJsonNoEvents(subscriptionId, bundleId, startDate,
                                                                                                productName, productCategory, billingPeriod,
-                                                                                               priceList, chargedThroughDate);
+                                                                                               priceList, chargedThroughDate, endDate);
         Assert.assertEquals(subscriptionJsonNoEvents.getSubscriptionId(), subscriptionId);
         Assert.assertEquals(subscriptionJsonNoEvents.getBundleId(), bundleId);
         Assert.assertEquals(subscriptionJsonNoEvents.getStartDate(), startDate);
@@ -74,7 +76,8 @@ public class TestSubscriptionJsonNoEvents {
                 "\"productCategory\":\"" + subscriptionJsonNoEvents.getProductCategory() + "\"," +
                 "\"billingPeriod\":\"" + subscriptionJsonNoEvents.getBillingPeriod() + "\"," +
                 "\"priceList\":\"" + subscriptionJsonNoEvents.getPriceList() + "\"," +
-                "\"chargedThroughDate\":\"" + subscriptionJsonNoEvents.getChargedThroughDate().toDateTimeISO().toString() + "\"}");
+                "\"chargedThroughDate\":\"" + subscriptionJsonNoEvents.getChargedThroughDate().toDateTimeISO().toString() + "\"," +
+                "\"cancelledDate\":\"" + subscriptionJsonNoEvents.getCancelledDate().toDateTimeISO().toString() + "\"}");
 
         final SubscriptionJsonNoEvents fromJson = mapper.readValue(asJson, SubscriptionJsonNoEvents.class);
         Assert.assertEquals(fromJson, subscriptionJsonNoEvents);
diff --git a/junction/src/main/java/com/ning/billing/junction/plumbing/api/BlockingSubscription.java b/junction/src/main/java/com/ning/billing/junction/plumbing/api/BlockingSubscription.java
index fb41a88..bfce70b 100644
--- a/junction/src/main/java/com/ning/billing/junction/plumbing/api/BlockingSubscription.java
+++ b/junction/src/main/java/com/ning/billing/junction/plumbing/api/BlockingSubscription.java
@@ -49,18 +49,22 @@ public class BlockingSubscription implements Subscription {
         this.checker = checker;
     }
 
+    @Override
     public UUID getId() {
         return subscription.getId();
     }
 
+    @Override
     public boolean cancel(final DateTime requestedDate, final boolean eot, final CallContext context) throws EntitlementUserApiException {
         return subscription.cancel(requestedDate, eot, context);
     }
 
+    @Override
     public boolean uncancel(final CallContext context) throws EntitlementUserApiException {
         return subscription.uncancel(context);
     }
 
+    @Override
     public boolean changePlan(final String productName, final BillingPeriod term, final String planSet, final DateTime requestedDate,
                               final CallContext context) throws EntitlementUserApiException {
         try {
@@ -71,59 +75,78 @@ public class BlockingSubscription implements Subscription {
         return subscription.changePlan(productName, term, planSet, requestedDate, context);
     }
 
+    @Override
     public boolean recreate(final PlanPhaseSpecifier spec, final DateTime requestedDate, final CallContext context)
             throws EntitlementUserApiException {
         return subscription.recreate(spec, requestedDate, context);
     }
 
+    @Override
     public UUID getBundleId() {
         return subscription.getBundleId();
     }
 
+    @Override
     public SubscriptionState getState() {
         return subscription.getState();
     }
 
+    @Override
     public DateTime getStartDate() {
         return subscription.getStartDate();
     }
 
+    @Override
     public DateTime getEndDate() {
         return subscription.getEndDate();
     }
 
+    @Override
+    public DateTime getFutureEndDate() {
+        return subscription.getFutureEndDate();
+    }
+
+    @Override
     public Plan getCurrentPlan() {
         return subscription.getCurrentPlan();
     }
 
+    @Override
     public PriceList getCurrentPriceList() {
         return subscription.getCurrentPriceList();
     }
 
+    @Override
     public PlanPhase getCurrentPhase() {
         return subscription.getCurrentPhase();
     }
 
+    @Override
     public DateTime getChargedThroughDate() {
         return subscription.getChargedThroughDate();
     }
 
+    @Override
     public DateTime getPaidThroughDate() {
         return subscription.getPaidThroughDate();
     }
 
+    @Override
     public ProductCategory getCategory() {
         return subscription.getCategory();
     }
 
+    @Override
     public EffectiveSubscriptionEvent getPendingTransition() {
         return subscription.getPendingTransition();
     }
 
+    @Override
     public EffectiveSubscriptionEvent getPreviousTransition() {
         return subscription.getPreviousTransition();
     }
 
+    @Override
     public List<EffectiveSubscriptionEvent> getBillingTransitions() {
         return subscription.getBillingTransitions();
     }
@@ -133,6 +156,7 @@ public class BlockingSubscription implements Subscription {
         return subscription.getAllTransitions();
     }
 
+    @Override
     public BlockingState getBlockingState() {
         if (blockingState == null) {
             blockingState = blockingApi.getBlockingStateFor(this);
@@ -143,4 +167,5 @@ public class BlockingSubscription implements Subscription {
     public Subscription getDelegateSubscription() {
         return subscription;
     }
+
 }
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 1b7008a..160fa9b 100644
--- a/server/src/test/java/com/ning/billing/jaxrs/TestJaxrsBase.java
+++ b/server/src/test/java/com/ning/billing/jaxrs/TestJaxrsBase.java
@@ -1,4 +1,4 @@
-/* 
+/*
  * Copyright 2010-2011 Ning, Inc.
  *
  * Ning licenses this file to you under the Apache License, version 2.0
@@ -192,11 +192,12 @@ public class TestJaxrsBase {
             }
         }
 
+        @Override
         protected void installKillbillModules() {
 
             /*
              * For a lack of getting module override working, copy all install modules from parent class...
-             * 
+             *
             super.installKillbillModules();
             Modules.override(new com.ning.billing.payment.setup.PaymentModule()).with(new PaymentMockModule());
             */
@@ -258,7 +259,7 @@ public class TestJaxrsBase {
         mapper.registerModule(new JodaModule());
         mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
 
-        //mapper.setPropertyNamingStrategy(new PropertyNamingStrategy.LowerCaseWithUnderscoresStrategy());        
+        //mapper.setPropertyNamingStrategy(new PropertyNamingStrategy.LowerCaseWithUnderscoresStrategy());
 
         busHandler = new TestApiListener(null);
         this.helper = listener.getMysqlTestingHelper();
@@ -427,7 +428,7 @@ public class TestJaxrsBase {
 
     protected SubscriptionJsonNoEvents createSubscription(final String bundleId, final String productName, final String productCategory, final String billingPeriod, final boolean waitCompletion) throws Exception {
 
-        final SubscriptionJsonNoEvents input = new SubscriptionJsonNoEvents(null, bundleId, null, productName, productCategory, billingPeriod, PriceListSet.DEFAULT_PRICELIST_NAME, null);
+        final SubscriptionJsonNoEvents input = new SubscriptionJsonNoEvents(null, bundleId, null, productName, productCategory, billingPeriod, PriceListSet.DEFAULT_PRICELIST_NAME, null, null);
         String baseJson = mapper.writeValueAsString(input);
 
 
diff --git a/server/src/test/java/com/ning/billing/jaxrs/TestSubscription.java b/server/src/test/java/com/ning/billing/jaxrs/TestSubscription.java
index dff76bd..4997c96 100644
--- a/server/src/test/java/com/ning/billing/jaxrs/TestSubscription.java
+++ b/server/src/test/java/com/ning/billing/jaxrs/TestSubscription.java
@@ -1,4 +1,4 @@
-/* 
+/*
  * Copyright 2010-2011 Ning, Inc.
  *
  * Ning licenses this file to you under the Apache License, version 2.0
@@ -36,6 +36,7 @@ import com.ning.billing.jaxrs.resources.JaxrsResource;
 import com.ning.http.client.Response;
 
 import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
 import static org.testng.Assert.assertTrue;
 
 public class TestSubscription extends TestJaxrsBase {
@@ -80,7 +81,7 @@ public class TestSubscription extends TestJaxrsBase {
                                                                          newProductName,
                                                                          subscriptionJson.getProductCategory(),
                                                                          subscriptionJson.getBillingPeriod(),
-                                                                         subscriptionJson.getPriceList(), null);
+                                                                         subscriptionJson.getPriceList(), null, null);
         baseJson = mapper.writeValueAsString(newInput);
 
         final Map<String, String> queryParams = getQueryParamsForCallCompletion(CALL_COMPLETION_TIMEOUT_SEC);
@@ -96,12 +97,22 @@ public class TestSubscription extends TestJaxrsBase {
 
         crappyWaitForLackOfProperSynchonization();
 
-        //      
+        //
         // Cancel EOT
         uri = JaxrsResource.SUBSCRIPTIONS_PATH + "/" + subscriptionJson.getSubscriptionId().toString();
         response = doDelete(uri, queryParams, DEFAULT_HTTP_TIMEOUT_SEC);
         assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
 
+
+        // Retrieves to check EndDate
+        uri = JaxrsResource.SUBSCRIPTIONS_PATH + "/" + subscriptionJson.getSubscriptionId().toString();
+        response = doGet(uri, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
+        assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
+        baseJson = response.getResponseBody();
+        objFromJson = mapper.readValue(baseJson, SubscriptionJsonNoEvents.class);
+        assertNotNull(objFromJson.getCancelledDate());
+        assertTrue(objFromJson.getCancelledDate().compareTo(clock.getUTCNow()) > 0);
+
         // Uncancel
         uri = JaxrsResource.SUBSCRIPTIONS_PATH + "/" + subscriptionJson.getSubscriptionId().toString() + "/uncancel";
         response = doPut(uri, baseJson, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
@@ -111,7 +122,8 @@ public class TestSubscription extends TestJaxrsBase {
     @Test(groups = "slow", enabled = true)
     public void testWithNonExistentSubscription() throws Exception {
         final String uri = JaxrsResource.SUBSCRIPTIONS_PATH + "/" + UUID.randomUUID().toString();
-        final SubscriptionJsonNoEvents subscriptionJson = new SubscriptionJsonNoEvents(null, UUID.randomUUID().toString(), null, "Pistol", ProductCategory.BASE.toString(), BillingPeriod.MONTHLY.toString(), PriceListSet.DEFAULT_PRICELIST_NAME, null);
+        final SubscriptionJsonNoEvents subscriptionJson = new SubscriptionJsonNoEvents(null, UUID.randomUUID().toString(), null, "Pistol", ProductCategory.BASE.toString(), BillingPeriod.MONTHLY.toString(),
+                PriceListSet.DEFAULT_PRICELIST_NAME, null, null);
         final String baseJson = mapper.writeValueAsString(subscriptionJson);
 
         Response response = doPut(uri, baseJson, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
diff --git a/util/src/test/java/com/ning/billing/mock/MockSubscription.java b/util/src/test/java/com/ning/billing/mock/MockSubscription.java
index 447cb08..af6628d 100644
--- a/util/src/test/java/com/ning/billing/mock/MockSubscription.java
+++ b/util/src/test/java/com/ning/billing/mock/MockSubscription.java
@@ -66,80 +66,99 @@ public class MockSubscription implements Subscription {
 
     Subscription sub = BrainDeadProxyFactory.createBrainDeadProxyFor(Subscription.class);
 
+    @Override
     public boolean cancel(final DateTime requestedDate, final boolean eot, final CallContext context) throws EntitlementUserApiException {
         return sub.cancel(requestedDate, eot, context);
     }
 
+    @Override
     public boolean uncancel(final CallContext context) throws EntitlementUserApiException {
         return sub.uncancel(context);
     }
 
+    @Override
     public boolean changePlan(final String productName, final BillingPeriod term, final String planSet, final DateTime requestedDate,
                               final CallContext context) throws EntitlementUserApiException {
         return sub.changePlan(productName, term, planSet, requestedDate, context);
     }
 
+    @Override
     public boolean recreate(final PlanPhaseSpecifier spec, final DateTime requestedDate, final CallContext context)
             throws EntitlementUserApiException {
         return sub.recreate(spec, requestedDate, context);
     }
 
+    @Override
     public UUID getId() {
         return id;
     }
 
+    @Override
     public UUID getBundleId() {
         return bundleId;
     }
 
+    @Override
     public SubscriptionState getState() {
         return state;
     }
 
+    @Override
     public DateTime getStartDate() {
         return startDate;
     }
 
+    @Override
     public DateTime getEndDate() {
         return sub.getEndDate();
     }
 
+    @Override
     public Plan getCurrentPlan() {
         return plan;
     }
 
+    @Override
     public BlockingState getBlockingState() {
         return sub.getBlockingState();
     }
 
+    @Override
     public PriceList getCurrentPriceList() {
         return new MockPriceList();
     }
 
+    @Override
     public PlanPhase getCurrentPhase() {
         return phase;
     }
 
+    @Override
     public DateTime getChargedThroughDate() {
         return sub.getChargedThroughDate();
     }
 
+    @Override
     public DateTime getPaidThroughDate() {
         return sub.getPaidThroughDate();
     }
 
+    @Override
     public ProductCategory getCategory() {
         return sub.getCategory();
     }
 
+    @Override
     public EffectiveSubscriptionEvent getPendingTransition() {
         return sub.getPendingTransition();
     }
 
+    @Override
     public EffectiveSubscriptionEvent getPreviousTransition() {
         return sub.getPreviousTransition();
     }
 
+    @Override
     public List<EffectiveSubscriptionEvent> getBillingTransitions() {
         return transitions;
     }
@@ -148,4 +167,10 @@ public class MockSubscription implements Subscription {
     public List<EffectiveSubscriptionEvent> getAllTransitions() {
         return transitions;
     }
+
+    @Override
+    public DateTime getFutureEndDate() {
+        // TODO Auto-generated method stub
+        return null;
+    }
 }