killbill-aplcache
Changes
entitlement/src/main/java/com/ning/billing/entitlement/api/repair/DefaultEntitlementRepairApi.java 48(+42 -6)
entitlement/src/main/java/com/ning/billing/entitlement/api/repair/DefaultSubscriptionRepair.java 15(+12 -3)
entitlement/src/main/java/com/ning/billing/entitlement/api/repair/RepairSubscriptionFactory.java 9(+7 -2)
entitlement/src/main/java/com/ning/billing/entitlement/api/repair/SubscriptionDataRepair.java 46(+40 -6)
entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/RepairEntitlementDao.java 32(+22 -10)
Details
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/alignment/PlanAligner.java b/entitlement/src/main/java/com/ning/billing/entitlement/alignment/PlanAligner.java
index 88f0d08..8006a39 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/alignment/PlanAligner.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/alignment/PlanAligner.java
@@ -129,6 +129,7 @@ public class PlanAligner {
// If we never had any Plan change, borrow the logics for createPlan alignment
case MIGRATE_ENTITLEMENT:
case CREATE:
+ case RE_CREATE:
List<TimedPhase> timedPhases = getTimedPhaseOnCreate(subscription.getStartDate(),
subscription.getBundleStartDate(),
lastPlanTransition.getNextPlan(),
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/api/repair/DefaultEntitlementRepairApi.java b/entitlement/src/main/java/com/ning/billing/entitlement/api/repair/DefaultEntitlementRepairApi.java
index 547cc93..e7cd999 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/api/repair/DefaultEntitlementRepairApi.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/api/repair/DefaultEntitlementRepairApi.java
@@ -56,6 +56,14 @@ public class DefaultEntitlementRepairApi implements EntitlementRepairApi {
private final SubscriptionFactory factory;
private final RepairEntitlementLifecycleDao repairDao;
+
+ private enum RepairType {
+ BASE_REPAIR,
+ ADD_ON_REPAIR,
+ STANDALONE_REPAIR
+ }
+
+
@Inject
public DefaultEntitlementRepairApi(@Named(EntitlementModule.REPAIR_NAMED) final SubscriptionFactory factory,
@Named(EntitlementModule.REPAIR_NAMED) final RepairEntitlementLifecycleDao repairDao, final EntitlementDao dao) {
@@ -82,6 +90,7 @@ public class DefaultEntitlementRepairApi implements EntitlementRepairApi {
return createGetBundleRepair(bundleId, viewId, repairs);
}
+
@Override
public BundleRepair repairBundle(final BundleRepair input, final boolean dryRun, final CallContext context)
@@ -116,6 +125,7 @@ public class DefaultEntitlementRepairApi implements EntitlementRepairApi {
List<SubscriptionDataRepair> inRepair = new LinkedList<SubscriptionDataRepair>();
for (Subscription cur : subscriptions) {
+ //
SubscriptionRepair curRepair = findAndCreateSubscriptionRepair(cur.getId(), input.getSubscriptions());
if (curRepair != null) {
SubscriptionDataRepair curInputRepair = ((SubscriptionDataRepair) cur);
@@ -166,10 +176,29 @@ public class DefaultEntitlementRepairApi implements EntitlementRepairApi {
}
}
- // This is a pure AO repair
- if (baseSubscriptionRepair == null && subscriptions.get(0).getCategory() == ProductCategory.BASE) {
- SubscriptionDataRepair baseSubscription = (SubscriptionDataRepair) subscriptions.get(0);
- baseSubscriptionRepair = createSubscriptionDataRepair(baseSubscription, baseSubscription.getBundleStartDate(), baseSubscription.getStartDate(), baseSubscription.getEvents());
+ final RepairType repairType = getRepairType(subscriptions.get(0), (baseSubscriptionRepair != null));
+ switch(repairType) {
+ case BASE_REPAIR:
+ // We need to add any existing addon that are not in the input repair list
+ for (Subscription cur : subscriptions) {
+ if (cur.getCategory() == ProductCategory.ADD_ON && !inRepair.contains(cur)) {
+ SubscriptionDataRepair curOutputRepair = createSubscriptionDataRepair((SubscriptionDataRepair) cur, newBundleStartDate, null, ((SubscriptionDataRepair) cur).getEvents());
+ repairDao.initializeRepair(curOutputRepair.getId(), ((SubscriptionDataRepair) cur).getEvents());
+ inRepair.add(curOutputRepair);
+ addOnSubscriptionInRepair.add(curOutputRepair);
+ }
+ }
+
+ break;
+ case ADD_ON_REPAIR:
+ // We need to set the baseSubscription as it is useful to calculate addon validity
+ SubscriptionDataRepair baseSubscription = (SubscriptionDataRepair) subscriptions.get(0);
+ baseSubscriptionRepair = createSubscriptionDataRepair(baseSubscription, baseSubscription.getBundleStartDate(), baseSubscription.getStartDate(), baseSubscription.getEvents());
+ break;
+ case STANDALONE_REPAIR:
+ default:
+ break;
+
}
validateBasePlanRecreate(isBasePlanRecreate, subscriptions, input.getSubscriptions());
@@ -199,6 +228,13 @@ public class DefaultEntitlementRepairApi implements EntitlementRepairApi {
}
}
+ private RepairType getRepairType(final Subscription firstSubscription, final boolean gotBaseSubscription) {
+ if (firstSubscription.getCategory() == ProductCategory.BASE) {
+ return gotBaseSubscription ? RepairType.BASE_REPAIR : RepairType.ADD_ON_REPAIR;
+ } else {
+ return RepairType.STANDALONE_REPAIR;
+ }
+ }
private void validateBasePlanRecreate(boolean isBasePlanRecreate, List<Subscription> subscriptions, List<SubscriptionRepair> input)
throws EntitlementRepairException {
@@ -240,11 +276,11 @@ public class DefaultEntitlementRepairApi implements EntitlementRepairApi {
throws EntitlementRepairException {
if (lastBPRemainingTime != null &&
firstNewEvent.getRequestedDate().isBefore(lastBPRemainingTime)) {
- throw new EntitlementRepairException(ErrorCode.ENT_REPAIR_NEW_EVENT_BEFORE_LAST_BP_REMAINING, firstNewEvent.getPlanPhaseSpecifier().toString(), data.getId());
+ throw new EntitlementRepairException(ErrorCode.ENT_REPAIR_NEW_EVENT_BEFORE_LAST_BP_REMAINING, firstNewEvent.getSubscriptionTransitionType(), data.getId());
}
if (lastRemainingTime != null &&
firstNewEvent.getRequestedDate().isBefore(lastRemainingTime)) {
- throw new EntitlementRepairException(ErrorCode.ENT_REPAIR_NEW_EVENT_BEFORE_LAST_AO_REMAINING, firstNewEvent.getPlanPhaseSpecifier().toString(), data.getId());
+ throw new EntitlementRepairException(ErrorCode.ENT_REPAIR_NEW_EVENT_BEFORE_LAST_AO_REMAINING, firstNewEvent.getSubscriptionTransitionType(), data.getId());
}
}
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/api/repair/DefaultSubscriptionRepair.java b/entitlement/src/main/java/com/ning/billing/entitlement/api/repair/DefaultSubscriptionRepair.java
index efae0b5..297825c 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/api/repair/DefaultSubscriptionRepair.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/api/repair/DefaultSubscriptionRepair.java
@@ -41,13 +41,22 @@ public class DefaultSubscriptionRepair implements SubscriptionRepair {
private final List<NewEvent> newEvents;
private final List<DeletedEvent> deletedEvents;
+ public DefaultSubscriptionRepair(final UUID id) {
+ this.id = id;
+ this.existingEvents = Collections.<SubscriptionRepair.ExistingEvent>emptyList();
+ this.deletedEvents = Collections.<SubscriptionRepair.DeletedEvent>emptyList();
+ this.newEvents = Collections.<SubscriptionRepair.NewEvent>emptyList();
+ }
public DefaultSubscriptionRepair(SubscriptionRepair input) {
this.id = input.getId();
- this.existingEvents = (input.getExistingEvents() != null) ? new ArrayList<SubscriptionRepair.ExistingEvent>(input.getExistingEvents()) : Collections.<SubscriptionRepair.ExistingEvent>emptyList();
+ this.existingEvents = (input.getExistingEvents() != null) ? new ArrayList<SubscriptionRepair.ExistingEvent>(input.getExistingEvents()) :
+ Collections.<SubscriptionRepair.ExistingEvent>emptyList();
sortExistingEvent(this.existingEvents);
- this.deletedEvents = (input.getDeletedEvents() != null) ? new ArrayList<SubscriptionRepair.DeletedEvent>(input.getDeletedEvents()) : Collections.<SubscriptionRepair.DeletedEvent>emptyList();
- this.newEvents = (input.getNewEvents() != null) ? new ArrayList<SubscriptionRepair.NewEvent>(input.getNewEvents()) : null;
+ this.deletedEvents = (input.getDeletedEvents() != null) ? new ArrayList<SubscriptionRepair.DeletedEvent>(input.getDeletedEvents()) :
+ Collections.<SubscriptionRepair.DeletedEvent>emptyList();
+ this.newEvents = (input.getNewEvents() != null) ? new ArrayList<SubscriptionRepair.NewEvent>(input.getNewEvents()) :
+ Collections.<SubscriptionRepair.NewEvent>emptyList();
sortNewEvent(this.newEvents);
}
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/api/repair/RepairSubscriptionFactory.java b/entitlement/src/main/java/com/ning/billing/entitlement/api/repair/RepairSubscriptionFactory.java
index a76599e..01a9328 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/api/repair/RepairSubscriptionFactory.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/api/repair/RepairSubscriptionFactory.java
@@ -27,6 +27,7 @@ import com.ning.billing.entitlement.api.user.DefaultSubscriptionFactory;
import com.ning.billing.entitlement.api.user.SubscriptionData;
import com.ning.billing.entitlement.api.user.DefaultSubscriptionFactory.SubscriptionBuilder;
import com.ning.billing.entitlement.engine.addon.AddonUtils;
+import com.ning.billing.entitlement.engine.dao.EntitlementDao;
import com.ning.billing.entitlement.events.EntitlementEvent;
import com.ning.billing.entitlement.glue.EntitlementModule;
import com.ning.billing.util.clock.Clock;
@@ -34,17 +35,21 @@ import com.ning.billing.util.clock.Clock;
public class RepairSubscriptionFactory extends DefaultSubscriptionFactory implements SubscriptionFactory {
private final AddonUtils addonUtils;
+ private final EntitlementDao repairDao;
@Inject
- public RepairSubscriptionFactory(@Named(EntitlementModule.REPAIR_NAMED) SubscriptionApiService apiService, Clock clock, CatalogService catalogService, AddonUtils addonUtils) {
+ public RepairSubscriptionFactory(@Named(EntitlementModule.REPAIR_NAMED) SubscriptionApiService apiService,
+ @Named(EntitlementModule.REPAIR_NAMED) EntitlementDao dao,
+ Clock clock, CatalogService catalogService, AddonUtils addonUtils) {
super(apiService, clock, catalogService);
this.addonUtils = addonUtils;
+ this.repairDao = dao;
}
@Override
public SubscriptionData createSubscription(SubscriptionBuilder builder,
List<EntitlementEvent> events) {
- SubscriptionData subscription = new SubscriptionDataRepair(builder, events, apiService, clock, addonUtils);
+ SubscriptionData subscription = new SubscriptionDataRepair(builder, events, apiService, repairDao, clock, addonUtils, catalogService);
subscription.rebuildTransitions(events, catalogService.getFullCatalog());
return subscription;
}
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/api/repair/SubscriptionDataRepair.java b/entitlement/src/main/java/com/ning/billing/entitlement/api/repair/SubscriptionDataRepair.java
index b983b55..809c23c 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/api/repair/SubscriptionDataRepair.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/api/repair/SubscriptionDataRepair.java
@@ -21,12 +21,14 @@ import java.util.LinkedList;
import java.util.List;
import org.joda.time.DateTime;
+import org.omg.CORBA.Request;
import com.google.common.base.Predicate;
import com.google.common.collect.Collections2;
import com.ning.billing.ErrorCode;
import com.ning.billing.catalog.api.Catalog;
import com.ning.billing.catalog.api.CatalogApiException;
+import com.ning.billing.catalog.api.CatalogService;
import com.ning.billing.catalog.api.Plan;
import com.ning.billing.catalog.api.PlanPhaseSpecifier;
import com.ning.billing.catalog.api.Product;
@@ -36,7 +38,11 @@ import com.ning.billing.entitlement.api.user.EntitlementUserApiException;
import com.ning.billing.entitlement.api.user.SubscriptionData;
import com.ning.billing.entitlement.api.user.DefaultSubscriptionFactory.SubscriptionBuilder;
import com.ning.billing.entitlement.engine.addon.AddonUtils;
+import com.ning.billing.entitlement.engine.dao.EntitlementDao;
import com.ning.billing.entitlement.events.EntitlementEvent;
+import com.ning.billing.entitlement.events.EntitlementEvent.EventType;
+import com.ning.billing.entitlement.events.user.ApiEventBuilder;
+import com.ning.billing.entitlement.events.user.ApiEventCancel;
import com.ning.billing.util.callcontext.CallContext;
import com.ning.billing.util.clock.Clock;
@@ -45,7 +51,9 @@ public class SubscriptionDataRepair extends SubscriptionData {
private final AddonUtils addonUtils;
private final Clock clock;
-
+ private final EntitlementDao repairDao;
+ private final CatalogService catalogService;
+
private final List<EntitlementEvent> initialEvents;
// Low level events are ONLY used for Repair APIs
@@ -53,17 +61,33 @@ public class SubscriptionDataRepair extends SubscriptionData {
public SubscriptionDataRepair(SubscriptionBuilder builder, List<EntitlementEvent> initialEvents, SubscriptionApiService apiService,
- Clock clock, AddonUtils addonUtils) {
+ EntitlementDao dao, Clock clock, AddonUtils addonUtils, CatalogService catalogService) {
super(builder, apiService, clock);
+ this.repairDao = dao;
this.addonUtils = addonUtils;
this.clock = clock;
+ this.catalogService = catalogService;
this.initialEvents = initialEvents;
}
+
+ DateTime getLastUserEventEffectiveDate() {
+ DateTime res = null;
+ for (EntitlementEvent cur : events) {
+ if (cur.getActiveVersion() != getActiveVersion()) {
+ break;
+ }
+ if (cur.getType() == EventType.PHASE) {
+ continue;
+ }
+ res = cur.getEffectiveDate();
+ }
+ return res;
+ }
+
public void addNewRepairEvent(final DefaultNewEvent input, final SubscriptionDataRepair baseSubscription, final List<SubscriptionDataRepair> addonSubscriptions, final CallContext context)
throws EntitlementRepairException {
-
try {
final PlanPhaseSpecifier spec = input.getPlanPhaseSpecifier();
switch(input.getSubscriptionTransitionType()) {
@@ -75,16 +99,17 @@ public class SubscriptionDataRepair extends SubscriptionData {
case CHANGE:
changePlan(spec.getProductName(), spec.getBillingPeriod(), spec.getPriceListName(), input.getRequestedDate(), context);
checkAddonRights(baseSubscription);
+ trickleDownBPEffectForAddon(addonSubscriptions, getLastUserEventEffectiveDate(), context);
break;
case CANCEL:
cancel(input.getRequestedDate(), false, context);
+ trickleDownBPEffectForAddon(addonSubscriptions, getLastUserEventEffectiveDate(), context);
break;
case PHASE:
break;
default:
throw new EntitlementRepairException(ErrorCode.ENT_REPAIR_UNKNOWN_TYPE, input.getSubscriptionTransitionType(), id);
}
- trickleDownBPEffectForAddon(addonSubscriptions, input.getRequestedDate(), context);
} catch (EntitlementUserApiException e) {
throw new EntitlementRepairException(e);
@@ -94,7 +119,7 @@ public class SubscriptionDataRepair extends SubscriptionData {
}
- private void trickleDownBPEffectForAddon(final List<SubscriptionDataRepair> addonSubscriptions, final DateTime requestedDate, final CallContext context)
+ private void trickleDownBPEffectForAddon(final List<SubscriptionDataRepair> addonSubscriptions, final DateTime effectiveDate, final CallContext context)
throws EntitlementUserApiException {
if (category != ProductCategory.BASE) {
@@ -117,7 +142,16 @@ public class SubscriptionDataRepair extends SubscriptionData {
addonUtils.isAddonIncluded(baseProduct, addonCurrentPlan) ||
! addonUtils.isAddonAvailable(baseProduct, addonCurrentPlan)) {
- cur.cancel(requestedDate, false, context);
+ EntitlementEvent cancelEvent = new ApiEventCancel(new ApiEventBuilder()
+ .setSubscriptionId(cur.getId())
+ .setActiveVersion(cur.getActiveVersion())
+ .setProcessedDate(now)
+ .setEffectiveDate(effectiveDate)
+ .setRequestedDate(now)
+ .setUserToken(context.getUserToken())
+ .setFromDisk(true));
+ repairDao.cancelSubscription(cur.getId(), cancelEvent, context, 0);
+ cur.rebuildTransitions(repairDao.getEventsForSubscription(cur.getId()), catalogService.getFullCatalog());
}
}
}
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 5e9f53b..9bfaa70 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
@@ -239,6 +239,32 @@ public class SubscriptionData extends ExtendedEntityBase implements
return paidThroughDate;
}
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result
+ + ((id == null) ? 0 : id.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ SubscriptionData other = (SubscriptionData) obj;
+ if (id == null) {
+ if (other.id != null)
+ return false;
+ } else if (!id.equals(other.id))
+ return false;
+ return true;
+ }
+
public List<SubscriptionEventTransition> getBillingTransitions() {
if (transitions == null) {
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/engine/core/Engine.java b/entitlement/src/main/java/com/ning/billing/entitlement/engine/core/Engine.java
index f22b2a3..453020c 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/engine/core/Engine.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/engine/core/Engine.java
@@ -148,9 +148,6 @@ public class Engine implements EventListener, EntitlementService {
final CallContext context = factory.createCallContext("SubscriptionEventQueue", CallOrigin.INTERNAL, UserType.SYSTEM, userToken);
processEventReady(event, key.getSeqId(), context);
}
-
-
-
},
new NotificationConfig() {
@Override
@@ -214,6 +211,11 @@ public class Engine implements EventListener, EntitlementService {
log.warn("Failed to retrieve subscription for id %s", event.getSubscriptionId());
return;
}
+ if (subscription.getActiveVersion() > event.getActiveVersion()) {
+ // Skip repaired events
+ return;
+ }
+
//
// Do any internal processing on that event before we send the event to the bus
//
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/EntitlementSqlDao.java b/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/EntitlementSqlDao.java
index 85c203a..0281894 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/EntitlementSqlDao.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/EntitlementSqlDao.java
@@ -608,13 +608,18 @@ public class EntitlementSqlDao implements EntitlementDao {
TransactionStatus status) throws Exception {
EventSqlDao transEventDao = transactional.become(EventSqlDao.class);
- for (SubscriptionDataRepair cur : inRepair) {
+ for (final SubscriptionDataRepair cur : inRepair) {
transactional.updateForRepair(cur.getId().toString(), cur.getActiveVersion(), cur.getStartDate().toDate(), cur.getBundleStartDate().toDate(), context);
for (EntitlementEvent event : cur.getInitialEvents()) {
- transEventDao.updateVersion(event.getId().toString(), cur.getActiveVersion(), context);
+ transEventDao.updateVersion(event.getId().toString(), event.getActiveVersion(), context);
}
for (EntitlementEvent event : cur.getNewEvents()) {
transEventDao.insertEvent(event, context);
+ if (event.getEffectiveDate().isAfter(clock.getUTCNow())) {
+ recordFutureNotificationFromTransaction(transactional,
+ event.getEffectiveDate(),
+ new EntitlementNotificationKey(event.getId()));
+ }
}
}
return null;
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/RepairEntitlementDao.java b/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/RepairEntitlementDao.java
index dfb81d2..098dc4b 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/RepairEntitlementDao.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/RepairEntitlementDao.java
@@ -22,6 +22,7 @@ import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.TreeSet;
import java.util.UUID;
import com.ning.billing.entitlement.api.SubscriptionFactory;
@@ -42,23 +43,24 @@ public class RepairEntitlementDao implements EntitlementDao, RepairEntitlementLi
private final static class SubscriptionRepairEvent {
- private final List<EntitlementEvent> events;
+ private final Set<EntitlementEvent> events;
public SubscriptionRepairEvent(List<EntitlementEvent> initialEvents) {
- events = new LinkedList<EntitlementEvent>();
- if (initialEvents != null) {
- events.addAll(initialEvents);
- }
- }
- public List<EntitlementEvent> getEvents() {
- Collections.sort(events, new Comparator<EntitlementEvent>() {
+ events = new TreeSet<EntitlementEvent>(new Comparator<EntitlementEvent>() {
@Override
public int compare(EntitlementEvent o1, EntitlementEvent o2) {
return o1.compareTo(o2);
}
});
+ if (initialEvents != null) {
+ events.addAll(initialEvents);
+ }
+ }
+
+ public Set<EntitlementEvent> getEvents() {
return events;
}
+
public void addEvents(List<EntitlementEvent> newEvents) {
events.addAll(newEvents);
}
@@ -79,7 +81,7 @@ public class RepairEntitlementDao implements EntitlementDao, RepairEntitlementLi
@Override
public List<EntitlementEvent> getEventsForSubscription(UUID subscriptionId) {
SubscriptionRepairEvent target = getRepairSubscriptionEvents(subscriptionId);
- return target.getEvents();
+ return new LinkedList<EntitlementEvent>(target.getEvents());
}
@Override
@@ -97,7 +99,17 @@ public class RepairEntitlementDao implements EntitlementDao, RepairEntitlementLi
@Override
public void cancelSubscription(UUID subscriptionId,
EntitlementEvent cancelEvent, CallContext context, int cancelSeq) {
- addEvents(subscriptionId, Collections.singletonList(cancelEvent));
+ long activeVersion = cancelEvent.getActiveVersion();
+ addEvents(subscriptionId, Collections.singletonList(cancelEvent));
+ SubscriptionRepairEvent target = getRepairSubscriptionEvents(subscriptionId);
+ boolean foundCancelEvent = false;
+ for (EntitlementEvent cur : target.getEvents()) {
+ if (cur.getId().equals(cancelEvent.getId())) {
+ foundCancelEvent = true;
+ } else if (foundCancelEvent) {
+ cur.setActiveVersion(activeVersion - 1);
+ }
+ }
}
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/repair/TestRepairBP.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/repair/TestRepairBP.java
index 96b42c1..fe25958 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/repair/TestRepairBP.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/repair/TestRepairBP.java
@@ -43,13 +43,10 @@ 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.api.SubscriptionTransitionType;
-import com.ning.billing.entitlement.api.TestApiBase;
import com.ning.billing.entitlement.api.ApiTestListener.NextEvent;
import com.ning.billing.entitlement.api.repair.SubscriptionRepair.DeletedEvent;
import com.ning.billing.entitlement.api.repair.SubscriptionRepair.ExistingEvent;
import com.ning.billing.entitlement.api.repair.SubscriptionRepair.NewEvent;
-import com.ning.billing.entitlement.api.repair.TestApiBaseRepair.TestWithException;
-import com.ning.billing.entitlement.api.repair.TestApiBaseRepair.TestWithExceptionCallback;
import com.ning.billing.entitlement.api.user.Subscription;
import com.ning.billing.entitlement.api.user.Subscription.SubscriptionState;
import com.ning.billing.entitlement.api.user.EntitlementUserApiException;
@@ -243,7 +240,29 @@ public class TestRepairBP extends TestApiBaseRepair {
expected.add(createExistingEventForAssertion(SubscriptionTransitionType.PHASE, newBaseProduct, PhaseType.EVERGREEN,
ProductCategory.BASE, PriceListSet.DEFAULT_PRICELIST_NAME, BillingPeriod.MONTHLY, restartDate.plusDays(30)));
- testBPRepairCreate(true, startDate, clockShift, baseProduct, newBaseProduct, expected);
+ UUID baseSubscriptionId = testBPRepairCreate(true, startDate, clockShift, baseProduct, newBaseProduct, expected);
+
+ testListener.pushExpectedEvent(NextEvent.PHASE);
+ clock.addDeltaFromReality(getDurationDay(32));
+ assertTrue(testListener.isCompleted(5000));
+
+ // CHECK WHAT"S GOING ON AFTER WE MOVE CLOCK-- FUTURE MOTIFICATION SHOULD KICK IN
+ SubscriptionData subscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(baseSubscriptionId);
+
+ assertEquals(subscription.getActiveVersion(), SubscriptionEvents.INITIAL_VERSION + 1);
+ assertEquals(subscription.getBundleId(), bundle.getId());
+ assertEquals(subscription.getStartDate(), restartDate);
+ assertEquals(subscription.getBundleStartDate(), restartDate);
+
+ Plan currentPlan = subscription.getCurrentPlan();
+ assertNotNull(currentPlan);
+ assertEquals(currentPlan.getProduct().getName(), newBaseProduct);
+ assertEquals(currentPlan.getProduct().getCategory(), ProductCategory.BASE);
+ assertEquals(currentPlan.getBillingPeriod(), BillingPeriod.MONTHLY);
+
+ PlanPhase currentPhase = subscription.getCurrentPhase();
+ assertNotNull(currentPhase);
+ assertEquals(currentPhase.getPhaseType(), PhaseType.EVERGREEN);
}
@@ -267,7 +286,7 @@ public class TestRepairBP extends TestApiBaseRepair {
}
- private void testBPRepairCreate(boolean inTrial, DateTime startDate, int clockShift,
+ private UUID testBPRepairCreate(boolean inTrial, DateTime startDate, int clockShift,
String baseProduct, String newBaseProduct, List<ExistingEvent> expectedEvents) throws Exception {
// CREATE BP
@@ -367,6 +386,8 @@ public class TestRepairBP extends TestApiBaseRepair {
currentPhase = realRunBaseSubscription.getCurrentPhase();
assertNotNull(currentPhase);
assertEquals(currentPhase.getPhaseType(), PhaseType.TRIAL);
+
+ return baseSubscription.getId();
}
@Test(groups={"slow"})
@@ -387,7 +408,28 @@ public class TestRepairBP extends TestApiBaseRepair {
expected.add(createExistingEventForAssertion(SubscriptionTransitionType.PHASE, newBaseProduct, PhaseType.EVERGREEN,
ProductCategory.BASE, PriceListSet.DEFAULT_PRICELIST_NAME, BillingPeriod.MONTHLY, startDate.plusDays(30)));
- testBPRepairAddChange(true, startDate, clockShift, baseProduct, newBaseProduct, expected, 3);
+ UUID baseSubscriptionId = testBPRepairAddChange(true, startDate, clockShift, baseProduct, newBaseProduct, expected, 3);
+
+ // CHECK WHAT"S GOING ON AFTER WE MOVE CLOCK-- FUTURE MOTIFICATION SHOULD KICK IN
+ testListener.pushExpectedEvent(NextEvent.PHASE);
+ clock.addDeltaFromReality(getDurationDay(32));
+ assertTrue(testListener.isCompleted(5000));
+ SubscriptionData subscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(baseSubscriptionId);
+
+ assertEquals(subscription.getActiveVersion(), SubscriptionEvents.INITIAL_VERSION + 1);
+ assertEquals(subscription.getBundleId(), bundle.getId());
+ assertEquals(subscription.getStartDate(), startDate);
+ assertEquals(subscription.getBundleStartDate(), startDate);
+
+ Plan currentPlan = subscription.getCurrentPlan();
+ assertNotNull(currentPlan);
+ assertEquals(currentPlan.getProduct().getName(), newBaseProduct);
+ assertEquals(currentPlan.getProduct().getCategory(), ProductCategory.BASE);
+ assertEquals(currentPlan.getBillingPeriod(), BillingPeriod.MONTHLY);
+
+ PlanPhase currentPhase = subscription.getCurrentPhase();
+ assertNotNull(currentPhase);
+ assertEquals(currentPhase.getPhaseType(), PhaseType.EVERGREEN);
}
@Test(groups={"slow"})
@@ -411,7 +453,7 @@ public class TestRepairBP extends TestApiBaseRepair {
}
- private void testBPRepairAddChange(boolean inTrial, DateTime startDate, int clockShift,
+ private UUID testBPRepairAddChange(boolean inTrial, DateTime startDate, int clockShift,
String baseProduct, String newBaseProduct, List<ExistingEvent> expectedEvents, int expectedTransitions) throws Exception {
// CREATE BP
@@ -515,8 +557,76 @@ public class TestRepairBP extends TestApiBaseRepair {
} else {
assertEquals(currentPhase.getPhaseType(), PhaseType.EVERGREEN);
}
+ return baseSubscription.getId();
}
+ @Test(groups={"slow"})
+ public void testRepairWithFurureCancelEvent() throws Exception {
+
+ DateTime startDate = clock.getUTCNow();
+
+ // CREATE BP
+ Subscription baseSubscription = createSubscription("Shotgun", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, startDate);
+
+ // MOVE CLOCK -- OUT OF TRIAL
+ testListener.pushExpectedEvent(NextEvent.PHASE);
+ clock.setDeltaFromReality(getDurationDay(35), 0);
+ assertTrue(testListener.isCompleted(5000));
+
+ // SET CTD to BASE SUBSCRIPTION SP CANCEL OCCURS EOT
+ DateTime newChargedThroughDate = baseSubscription.getStartDate().plusDays(30).plusMonths(1);
+ billingApi.setChargedThroughDate(baseSubscription.getId(), newChargedThroughDate, context);
+ baseSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(baseSubscription.getId());
+
+
+ DateTime requestedChange = clock.getUTCNow();
+ baseSubscription.changePlan("Pistol", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, requestedChange, context);
+
+
+ // CHECK CHANGE DID NOT OCCUR YET
+ Plan currentPlan = baseSubscription.getCurrentPlan();
+ assertNotNull(currentPlan);
+ assertEquals(currentPlan.getProduct().getName(), "Shotgun");
+ assertEquals(currentPlan.getProduct().getCategory(), ProductCategory.BASE);
+ assertEquals(currentPlan.getBillingPeriod(), BillingPeriod.MONTHLY);
+
+
+ DateTime repairTime = clock.getUTCNow().minusDays(1);
+ BundleRepair bundleRepair = repairApi.getBundleRepair(bundle.getId());
+ sortEventsOnBundle(bundleRepair);
+
+ PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Assault-Rifle", ProductCategory.BASE, BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, PhaseType.EVERGREEN);
+
+ NewEvent ne = createNewEvent(SubscriptionTransitionType.CHANGE, repairTime, spec);
+ List<DeletedEvent> des = new LinkedList<SubscriptionRepair.DeletedEvent>();
+ des.add(createDeletedEvent(bundleRepair.getSubscriptions().get(0).getExistingEvents().get(2).getEventId()));
+
+ SubscriptionRepair sRepair = createSubscriptionReapir(baseSubscription.getId(), des, Collections.singletonList(ne));
+
+ // SKIP DRY RUN AND DO REPAIR...
+ BundleRepair bRepair = createBundleRepair(bundle.getId(), bundleRepair.getViewId(), Collections.singletonList(sRepair));
+
+ boolean dryRun = false;
+ repairApi.repairBundle(bRepair, dryRun, context);
+
+ baseSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(baseSubscription.getId());
+
+ assertEquals(((SubscriptionData) baseSubscription).getActiveVersion(), SubscriptionEvents.INITIAL_VERSION + 1);
+ assertEquals(baseSubscription.getBundleId(), bundle.getId());
+ assertEquals(baseSubscription.getStartDate(), baseSubscription.getStartDate());
+
+ currentPlan = baseSubscription.getCurrentPlan();
+ assertNotNull(currentPlan);
+ assertEquals(currentPlan.getProduct().getName(), "Assault-Rifle");
+ assertEquals(currentPlan.getProduct().getCategory(), ProductCategory.BASE);
+ assertEquals(currentPlan.getBillingPeriod(), BillingPeriod.MONTHLY);
+
+ PlanPhase currentPhase = baseSubscription.getCurrentPhase();
+ assertNotNull(currentPhase);
+ assertEquals(currentPhase.getPhaseType(), PhaseType.EVERGREEN);
+ }
+
+
// Needs real SQL backend to be tested properly
@Test(groups={"slow"})
public void testENT_REPAIR_VIEW_CHANGED_newEvent() throws Exception {
@@ -544,12 +654,11 @@ public class TestRepairBP extends TestApiBaseRepair {
BundleRepair bRepair = createBundleRepair(bundle.getId(), bundleRepair.getViewId(), Collections.singletonList(sRepair));
-
testListener.pushExpectedEvent(NextEvent.CHANGE);
DateTime changeTime = clock.getUTCNow();
baseSubscription.changePlan("Assault-Rifle", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, changeTime, context);
assertTrue(testListener.isCompleted(5000));
-
+
repairApi.repairBundle(bRepair, true, context);
}
}, ErrorCode.ENT_REPAIR_VIEW_CHANGED);
@@ -570,7 +679,6 @@ public class TestRepairBP extends TestApiBaseRepair {
@Override
public void doTest() throws EntitlementRepairException, EntitlementUserApiException {
- /*
BundleRepair bundleRepair = repairApi.getBundleRepair(bundle.getId());
sortEventsOnBundle(bundleRepair);
PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Assault-Rifle", ProductCategory.BASE, BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, PhaseType.EVERGREEN);
@@ -582,14 +690,11 @@ public class TestRepairBP extends TestApiBaseRepair {
BundleRepair bRepair = createBundleRepair(bundle.getId(), bundleRepair.getViewId(), Collections.singletonList(sRepair));
-
- testListener.pushExpectedEvent(NextEvent.CHANGE);
- DateTime changeTime = clock.getUTCNow();
- baseSubscription.changePlan("Assault-Rifle", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, changeTime, context);
- assertTrue(testListener.isCompleted(5000));
+ DateTime newChargedThroughDate = baseSubscription.getStartDate().plusDays(30).plusMonths(1);
+ billingApi.setChargedThroughDate(baseSubscription.getId(), newChargedThroughDate, context);
+ entitlementApi.getSubscriptionFromId(baseSubscription.getId());
repairApi.repairBundle(bRepair, true, context);
- */
}
}, ErrorCode.ENT_REPAIR_VIEW_CHANGED);
}
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/repair/TestRepairWithAO.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/repair/TestRepairWithAO.java
index ac28307..d238a6a 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/repair/TestRepairWithAO.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/repair/TestRepairWithAO.java
@@ -18,15 +18,12 @@ package com.ning.billing.entitlement.api.repair;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
-import java.util.UUID;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
-import static org.testng.Assert.assertNull;
import static org.testng.Assert.assertTrue;
import org.joda.time.DateTime;
-import org.testng.Assert;
import org.testng.annotations.Test;
import com.google.inject.Guice;
@@ -60,16 +57,409 @@ public class TestRepairWithAO extends TestApiBaseRepair {
@Test(groups={"slow"})
public void testRepairChangeBPWithAddonIncluded() throws Exception {
+ String baseProduct = "Shotgun";
+ BillingPeriod baseTerm = BillingPeriod.MONTHLY;
+ String basePriceList = PriceListSet.DEFAULT_PRICELIST_NAME;
+
+ // CREATE BP
+ SubscriptionData baseSubscription = createSubscription(baseProduct, baseTerm, basePriceList);
+
+ // MOVE CLOCK A LITTLE BIT-- STILL IN TRIAL
+ Duration someTimeLater = getDurationDay(3);
+ clock.setDeltaFromReality(someTimeLater, DAY_IN_MS);
+
+ SubscriptionData aoSubscription = createSubscription("Telescopic-Scope", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME);
+
+ SubscriptionData aoSubscription2 = createSubscription("Laser-Scope", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME);
+
+ // MOVE CLOCK A LITTLE BIT MORE -- STILL IN TRIAL
+ clock.addDeltaFromReality(someTimeLater);
+
+ BundleRepair bundleRepair = repairApi.getBundleRepair(bundle.getId());
+ sortEventsOnBundle(bundleRepair);
+
+ // Quick check
+ SubscriptionRepair bpRepair = getSubscriptionRepair(baseSubscription.getId(), bundleRepair);
+ assertEquals(bpRepair.getExistingEvents().size(), 2);
+
+ SubscriptionRepair aoRepair = getSubscriptionRepair(aoSubscription.getId(), bundleRepair);
+ assertEquals(aoRepair.getExistingEvents().size(), 2);
+
+ SubscriptionRepair aoRepair2 = getSubscriptionRepair(aoSubscription2.getId(), bundleRepair);
+ assertEquals(aoRepair2.getExistingEvents().size(), 2);
+
+ DateTime bpChangeDate = clock.getUTCNow().minusDays(1);
+
+ List<DeletedEvent> des = new LinkedList<SubscriptionRepair.DeletedEvent>();
+ des.add(createDeletedEvent(bpRepair.getExistingEvents().get(1).getEventId()));
+
+ PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Assault-Rifle", ProductCategory.BASE, BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, PhaseType.TRIAL);
+ NewEvent ne = createNewEvent(SubscriptionTransitionType.CHANGE, bpChangeDate, spec);
+
+ bpRepair = createSubscriptionReapir(baseSubscription.getId(), des, Collections.singletonList(ne));
+
+ bundleRepair = createBundleRepair(bundle.getId(), bundleRepair.getViewId(), Collections.singletonList(bpRepair));
+
+ boolean dryRun = true;
+ BundleRepair dryRunBundleRepair = repairApi.repairBundle(bundleRepair, dryRun, context);
+
+ aoRepair = getSubscriptionRepair(aoSubscription.getId(), dryRunBundleRepair);
+ assertEquals(aoRepair.getExistingEvents().size(), 2);
+
+ aoRepair2 = getSubscriptionRepair(aoSubscription2.getId(), dryRunBundleRepair);
+ assertEquals(aoRepair.getExistingEvents().size(), 2);
+
+ bpRepair = getSubscriptionRepair(baseSubscription.getId(), dryRunBundleRepair);
+ assertEquals(bpRepair.getExistingEvents().size(), 3);
+
+ // Check expected for AO
+ List<ExistingEvent> expectedAO = new LinkedList<SubscriptionRepair.ExistingEvent>();
+ expectedAO.add(createExistingEventForAssertion(SubscriptionTransitionType.CREATE, "Telescopic-Scope", PhaseType.DISCOUNT,
+ ProductCategory.ADD_ON, PriceListSet.DEFAULT_PRICELIST_NAME, BillingPeriod.MONTHLY, aoSubscription.getStartDate()));
+ expectedAO.add(createExistingEventForAssertion(SubscriptionTransitionType.CANCEL, null, null,
+ ProductCategory.ADD_ON, null, null, bpChangeDate));
+ int index = 0;
+ for (ExistingEvent e : expectedAO) {
+ validateExistingEventForAssertion(e, aoRepair.getExistingEvents().get(index++));
+ }
+
+ List<ExistingEvent> expectedAO2 = new LinkedList<SubscriptionRepair.ExistingEvent>();
+ expectedAO2.add(createExistingEventForAssertion(SubscriptionTransitionType.CREATE, "Laser-Scope", PhaseType.DISCOUNT,
+ ProductCategory.ADD_ON, PriceListSet.DEFAULT_PRICELIST_NAME, BillingPeriod.MONTHLY, aoSubscription2.getStartDate()));
+ expectedAO2.add(createExistingEventForAssertion(SubscriptionTransitionType.PHASE, "Laser-Scope", PhaseType.EVERGREEN,
+ ProductCategory.ADD_ON, PriceListSet.DEFAULT_PRICELIST_NAME, BillingPeriod.MONTHLY, aoSubscription2.getStartDate().plusMonths(1)));
+ index = 0;
+ for (ExistingEvent e : expectedAO2) {
+ validateExistingEventForAssertion(e, aoRepair2.getExistingEvents().get(index++));
+ }
+
+ // Check expected for BP
+ List<ExistingEvent> expectedBP = new LinkedList<SubscriptionRepair.ExistingEvent>();
+ expectedBP.add(createExistingEventForAssertion(SubscriptionTransitionType.CREATE, "Shotgun", PhaseType.TRIAL,
+ ProductCategory.BASE, PriceListSet.DEFAULT_PRICELIST_NAME, BillingPeriod.NO_BILLING_PERIOD, baseSubscription.getStartDate()));
+ expectedBP.add(createExistingEventForAssertion(SubscriptionTransitionType.CHANGE, "Assault-Rifle", PhaseType.TRIAL,
+ ProductCategory.BASE, PriceListSet.DEFAULT_PRICELIST_NAME, BillingPeriod.NO_BILLING_PERIOD, bpChangeDate));
+ expectedBP.add(createExistingEventForAssertion(SubscriptionTransitionType.PHASE, "Assault-Rifle", PhaseType.EVERGREEN,
+ ProductCategory.BASE, PriceListSet.DEFAULT_PRICELIST_NAME, BillingPeriod.MONTHLY, baseSubscription.getStartDate().plusDays(30)));
+ index = 0;
+ for (ExistingEvent e : expectedBP) {
+ validateExistingEventForAssertion(e, bpRepair.getExistingEvents().get(index++));
+ }
+
+
+ SubscriptionData newAoSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(aoSubscription.getId());
+ assertEquals(newAoSubscription.getState(), SubscriptionState.ACTIVE);
+ assertEquals(newAoSubscription.getAllTransitions().size(), 2);
+ assertEquals(newAoSubscription.getActiveVersion(), SubscriptionEvents.INITIAL_VERSION);
+
+ SubscriptionData newAoSubscription2 = (SubscriptionData) entitlementApi.getSubscriptionFromId(aoSubscription2.getId());
+ assertEquals(newAoSubscription2.getState(), SubscriptionState.ACTIVE);
+ assertEquals(newAoSubscription2.getAllTransitions().size(), 2);
+ assertEquals(newAoSubscription2.getActiveVersion(), SubscriptionEvents.INITIAL_VERSION);
+
+
+ SubscriptionData newBaseSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(baseSubscription.getId());
+ assertEquals(newBaseSubscription.getState(), SubscriptionState.ACTIVE);
+ assertEquals(newBaseSubscription.getAllTransitions().size(), 2);
+ assertEquals(newBaseSubscription.getActiveVersion(), SubscriptionEvents.INITIAL_VERSION);
+
+ dryRun = false;
+ BundleRepair realRunBundleRepair = repairApi.repairBundle(bundleRepair, dryRun, context);
+
+
+ aoRepair = getSubscriptionRepair(aoSubscription.getId(), realRunBundleRepair);
+ assertEquals(aoRepair.getExistingEvents().size(), 2);
+
+ bpRepair = getSubscriptionRepair(baseSubscription.getId(), realRunBundleRepair);
+ assertEquals(bpRepair.getExistingEvents().size(), 3);
+
+ index = 0;
+ for (ExistingEvent e : expectedAO) {
+ validateExistingEventForAssertion(e, aoRepair.getExistingEvents().get(index++));
+ }
+
+ index = 0;
+ for (ExistingEvent e : expectedAO2) {
+ validateExistingEventForAssertion(e, aoRepair2.getExistingEvents().get(index++));
+ }
+
+ index = 0;
+ for (ExistingEvent e : expectedBP) {
+ validateExistingEventForAssertion(e, bpRepair.getExistingEvents().get(index++));
+ }
+
+ newAoSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(aoSubscription.getId());
+ assertEquals(newAoSubscription.getState(), SubscriptionState.CANCELLED);
+ assertEquals(newAoSubscription.getAllTransitions().size(), 2);
+ assertEquals(newAoSubscription.getActiveVersion(), SubscriptionEvents.INITIAL_VERSION + 1);
+
+ newAoSubscription2 = (SubscriptionData) entitlementApi.getSubscriptionFromId(aoSubscription2.getId());
+ assertEquals(newAoSubscription2.getState(), SubscriptionState.ACTIVE);
+ assertEquals(newAoSubscription2.getAllTransitions().size(), 2);
+ assertEquals(newAoSubscription2.getActiveVersion(), SubscriptionEvents.INITIAL_VERSION + 1);
+
+
+ newBaseSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(baseSubscription.getId());
+ assertEquals(newBaseSubscription.getState(), SubscriptionState.ACTIVE);
+ assertEquals(newBaseSubscription.getAllTransitions().size(), 3);
+ assertEquals(newBaseSubscription.getActiveVersion(), SubscriptionEvents.INITIAL_VERSION + 1);
}
@Test(groups={"slow"})
public void testRepairChangeBPWithAddonNonAvailable() throws Exception {
+ String baseProduct = "Shotgun";
+ BillingPeriod baseTerm = BillingPeriod.MONTHLY;
+ String basePriceList = PriceListSet.DEFAULT_PRICELIST_NAME;
+
+ // CREATE BP
+ SubscriptionData baseSubscription = createSubscription(baseProduct, baseTerm, basePriceList);
+
+ // MOVE CLOCK A LITTLE BIT-- STILL IN TRIAL
+ Duration someTimeLater = getDurationDay(3);
+ clock.setDeltaFromReality(someTimeLater, DAY_IN_MS);
+
+ SubscriptionData aoSubscription = createSubscription("Telescopic-Scope", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME);
+
+ // MOVE CLOCK A LITTLE BIT MORE -- AFTER TRIAL
+ testListener.pushExpectedEvent(NextEvent.PHASE);
+ testListener.pushExpectedEvent(NextEvent.PHASE);
+ someTimeLater = getDurationDay(32);
+ clock.addDeltaFromReality(someTimeLater);
+ assertTrue(testListener.isCompleted(7000));
+
+ BundleRepair bundleRepair = repairApi.getBundleRepair(bundle.getId());
+ sortEventsOnBundle(bundleRepair);
+
+ // Quick check
+ SubscriptionRepair bpRepair = getSubscriptionRepair(baseSubscription.getId(), bundleRepair);
+ assertEquals(bpRepair.getExistingEvents().size(), 2);
+
+ SubscriptionRepair aoRepair = getSubscriptionRepair(aoSubscription.getId(), bundleRepair);
+ assertEquals(aoRepair.getExistingEvents().size(), 2);
+
+ DateTime bpChangeDate = clock.getUTCNow().minusDays(1);
+
+ PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Pistol", ProductCategory.BASE, BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, PhaseType.EVERGREEN);
+ NewEvent ne = createNewEvent(SubscriptionTransitionType.CHANGE, bpChangeDate, spec);
+
+ bpRepair = createSubscriptionReapir(baseSubscription.getId(), Collections.<SubscriptionRepair.DeletedEvent>emptyList(), Collections.singletonList(ne));
+
+ bundleRepair = createBundleRepair(bundle.getId(), bundleRepair.getViewId(), Collections.singletonList(bpRepair));
+
+ boolean dryRun = true;
+ BundleRepair dryRunBundleRepair = repairApi.repairBundle(bundleRepair, dryRun, context);
+
+ aoRepair = getSubscriptionRepair(aoSubscription.getId(), dryRunBundleRepair);
+ assertEquals(aoRepair.getExistingEvents().size(), 3);
+
+ bpRepair = getSubscriptionRepair(baseSubscription.getId(), dryRunBundleRepair);
+ assertEquals(bpRepair.getExistingEvents().size(), 3);
+
+ // Check expected for AO
+ List<ExistingEvent> expectedAO = new LinkedList<SubscriptionRepair.ExistingEvent>();
+ expectedAO.add(createExistingEventForAssertion(SubscriptionTransitionType.CREATE, "Telescopic-Scope", PhaseType.DISCOUNT,
+ ProductCategory.ADD_ON, PriceListSet.DEFAULT_PRICELIST_NAME, BillingPeriod.MONTHLY, aoSubscription.getStartDate()));
+ expectedAO.add(createExistingEventForAssertion(SubscriptionTransitionType.CREATE, "Telescopic-Scope", PhaseType.EVERGREEN,
+ ProductCategory.ADD_ON, PriceListSet.DEFAULT_PRICELIST_NAME, BillingPeriod.MONTHLY, baseSubscription.getStartDate().plusMonths(1)));
+ expectedAO.add(createExistingEventForAssertion(SubscriptionTransitionType.CANCEL, null, null,
+ ProductCategory.ADD_ON, null, null, bpChangeDate));
+ int index = 0;
+ for (ExistingEvent e : expectedAO) {
+ validateExistingEventForAssertion(e, aoRepair.getExistingEvents().get(index++));
+ }
+
+ // Check expected for BP
+ List<ExistingEvent> expectedBP = new LinkedList<SubscriptionRepair.ExistingEvent>();
+ expectedBP.add(createExistingEventForAssertion(SubscriptionTransitionType.CREATE, "Shotgun", PhaseType.TRIAL,
+ ProductCategory.BASE, PriceListSet.DEFAULT_PRICELIST_NAME, BillingPeriod.NO_BILLING_PERIOD, baseSubscription.getStartDate()));
+ expectedBP.add(createExistingEventForAssertion(SubscriptionTransitionType.PHASE, "Shotgun", PhaseType.EVERGREEN,
+ ProductCategory.BASE, PriceListSet.DEFAULT_PRICELIST_NAME, BillingPeriod.MONTHLY, baseSubscription.getStartDate().plusDays(30)));
+ expectedBP.add(createExistingEventForAssertion(SubscriptionTransitionType.CHANGE, "Pistol", PhaseType.EVERGREEN,
+ ProductCategory.BASE, PriceListSet.DEFAULT_PRICELIST_NAME, BillingPeriod.MONTHLY, bpChangeDate));
+ index = 0;
+ for (ExistingEvent e : expectedBP) {
+ validateExistingEventForAssertion(e, bpRepair.getExistingEvents().get(index++));
+ }
+
+ SubscriptionData newAoSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(aoSubscription.getId());
+ assertEquals(newAoSubscription.getState(), SubscriptionState.ACTIVE);
+ assertEquals(newAoSubscription.getAllTransitions().size(), 2);
+ assertEquals(newAoSubscription.getActiveVersion(), SubscriptionEvents.INITIAL_VERSION);
+
+ SubscriptionData newBaseSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(baseSubscription.getId());
+ assertEquals(newBaseSubscription.getState(), SubscriptionState.ACTIVE);
+ assertEquals(newBaseSubscription.getAllTransitions().size(), 2);
+ assertEquals(newBaseSubscription.getActiveVersion(), SubscriptionEvents.INITIAL_VERSION);
+
+ dryRun = false;
+ BundleRepair realRunBundleRepair = repairApi.repairBundle(bundleRepair, dryRun, context);
+
+ aoRepair = getSubscriptionRepair(aoSubscription.getId(), realRunBundleRepair);
+ assertEquals(aoRepair.getExistingEvents().size(), 3);
+
+ bpRepair = getSubscriptionRepair(baseSubscription.getId(), realRunBundleRepair);
+ assertEquals(bpRepair.getExistingEvents().size(), 3);
+
+ index = 0;
+ for (ExistingEvent e : expectedAO) {
+ validateExistingEventForAssertion(e, aoRepair.getExistingEvents().get(index++));
+ }
+
+ index = 0;
+ for (ExistingEvent e : expectedBP) {
+ validateExistingEventForAssertion(e, bpRepair.getExistingEvents().get(index++));
+ }
+
+ newAoSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(aoSubscription.getId());
+ assertEquals(newAoSubscription.getState(), SubscriptionState.CANCELLED);
+ assertEquals(newAoSubscription.getAllTransitions().size(), 3);
+ assertEquals(newAoSubscription.getActiveVersion(), SubscriptionEvents.INITIAL_VERSION + 1);
+
+ newBaseSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(baseSubscription.getId());
+ assertEquals(newBaseSubscription.getState(), SubscriptionState.ACTIVE);
+ assertEquals(newBaseSubscription.getAllTransitions().size(), 3);
+ assertEquals(newBaseSubscription.getActiveVersion(), SubscriptionEvents.INITIAL_VERSION + 1);
}
@Test(groups={"slow"})
- public void testRepairCancelBPWithAddons() throws Exception {
+ public void testRepairCancelBP_EOT_WithAddons() throws Exception {
+
+ String baseProduct = "Shotgun";
+ BillingPeriod baseTerm = BillingPeriod.MONTHLY;
+ String basePriceList = PriceListSet.DEFAULT_PRICELIST_NAME;
+
+ // CREATE BP
+ SubscriptionData baseSubscription = createSubscription(baseProduct, baseTerm, basePriceList);
+
+ // MOVE CLOCK A LITTLE BIT-- STILL IN TRIAL
+ Duration someTimeLater = getDurationDay(3);
+ clock.setDeltaFromReality(someTimeLater, DAY_IN_MS);
+
+ SubscriptionData aoSubscription = createSubscription("Telescopic-Scope", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME);
+
+ // MOVE CLOCK A LITTLE BIT MORE -- AFTER TRIAL
+ testListener.pushExpectedEvent(NextEvent.PHASE);
+ testListener.pushExpectedEvent(NextEvent.PHASE);
+ someTimeLater = getDurationDay(40);
+ clock.addDeltaFromReality(someTimeLater);
+ assertTrue(testListener.isCompleted(7000));
+
+ // SET CTD to BASE SUBSCRIPTION SP CANCEL OCCURS EOT
+ DateTime newChargedThroughDate = baseSubscription.getStartDate().plusDays(30).plusMonths(1);
+ billingApi.setChargedThroughDate(baseSubscription.getId(), newChargedThroughDate, context);
+ baseSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(baseSubscription.getId());
+
+ BundleRepair bundleRepair = repairApi.getBundleRepair(bundle.getId());
+ sortEventsOnBundle(bundleRepair);
+
+ // Quick check
+ SubscriptionRepair bpRepair = getSubscriptionRepair(baseSubscription.getId(), bundleRepair);
+ assertEquals(bpRepair.getExistingEvents().size(), 2);
+
+ SubscriptionRepair aoRepair = getSubscriptionRepair(aoSubscription.getId(), bundleRepair);
+ assertEquals(aoRepair.getExistingEvents().size(), 2);
+
+ DateTime bpCancelDate = clock.getUTCNow().minusDays(1);
+ NewEvent ne = createNewEvent(SubscriptionTransitionType.CANCEL, bpCancelDate, null);
+ bpRepair = createSubscriptionReapir(baseSubscription.getId(), Collections.<SubscriptionRepair.DeletedEvent>emptyList(), Collections.singletonList(ne));
+ bundleRepair = createBundleRepair(bundle.getId(), bundleRepair.getViewId(), Collections.singletonList(bpRepair));
+
+ boolean dryRun = true;
+ BundleRepair dryRunBundleRepair = repairApi.repairBundle(bundleRepair, dryRun, context);
+
+ aoRepair = getSubscriptionRepair(aoSubscription.getId(), dryRunBundleRepair);
+ assertEquals(aoRepair.getExistingEvents().size(), 2);
+
+ bpRepair = getSubscriptionRepair(baseSubscription.getId(), dryRunBundleRepair);
+ assertEquals(bpRepair.getExistingEvents().size(), 3);
+ // Check expected for AO
+ List<ExistingEvent> expectedAO = new LinkedList<SubscriptionRepair.ExistingEvent>();
+ expectedAO.add(createExistingEventForAssertion(SubscriptionTransitionType.CREATE, "Telescopic-Scope", PhaseType.DISCOUNT,
+ ProductCategory.ADD_ON, PriceListSet.DEFAULT_PRICELIST_NAME, BillingPeriod.MONTHLY, aoSubscription.getStartDate()));
+ expectedAO.add(createExistingEventForAssertion(SubscriptionTransitionType.PHASE, "Telescopic-Scope", PhaseType.EVERGREEN,
+ ProductCategory.ADD_ON, PriceListSet.DEFAULT_PRICELIST_NAME, BillingPeriod.MONTHLY, baseSubscription.getStartDate().plusMonths(1)));
+ /*
+ expectedAO.add(createExistingEventForAssertion(SubscriptionTransitionType.CANCEL, null, null,
+ ProductCategory.ADD_ON, null, null, newChargedThroughDate));
+ */
+ int index = 0;
+ for (ExistingEvent e : expectedAO) {
+ validateExistingEventForAssertion(e, aoRepair.getExistingEvents().get(index++));
+ }
+
+ // Check expected for BP
+ List<ExistingEvent> expectedBP = new LinkedList<SubscriptionRepair.ExistingEvent>();
+ expectedBP.add(createExistingEventForAssertion(SubscriptionTransitionType.CREATE, "Shotgun", PhaseType.TRIAL,
+ ProductCategory.BASE, PriceListSet.DEFAULT_PRICELIST_NAME, BillingPeriod.NO_BILLING_PERIOD, baseSubscription.getStartDate()));
+ expectedBP.add(createExistingEventForAssertion(SubscriptionTransitionType.PHASE, "Shotgun", PhaseType.EVERGREEN,
+ ProductCategory.BASE, PriceListSet.DEFAULT_PRICELIST_NAME, BillingPeriod.MONTHLY, baseSubscription.getStartDate().plusDays(30)));
+ expectedBP.add(createExistingEventForAssertion(SubscriptionTransitionType.CANCEL, null, null,
+ ProductCategory.BASE, null, null, newChargedThroughDate));
+ index = 0;
+ for (ExistingEvent e : expectedBP) {
+ validateExistingEventForAssertion(e, bpRepair.getExistingEvents().get(index++));
+ }
+
+ SubscriptionData newAoSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(aoSubscription.getId());
+ assertEquals(newAoSubscription.getState(), SubscriptionState.ACTIVE);
+ assertEquals(newAoSubscription.getAllTransitions().size(), 2);
+ assertEquals(newAoSubscription.getActiveVersion(), SubscriptionEvents.INITIAL_VERSION);
+
+ SubscriptionData newBaseSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(baseSubscription.getId());
+ assertEquals(newBaseSubscription.getState(), SubscriptionState.ACTIVE);
+ assertEquals(newBaseSubscription.getAllTransitions().size(), 2);
+ assertEquals(newBaseSubscription.getActiveVersion(), SubscriptionEvents.INITIAL_VERSION);
+
+ dryRun = false;
+ BundleRepair realRunBundleRepair = repairApi.repairBundle(bundleRepair, dryRun, context);
+
+ aoRepair = getSubscriptionRepair(aoSubscription.getId(), realRunBundleRepair);
+ assertEquals(aoRepair.getExistingEvents().size(), 3);
+
+ bpRepair = getSubscriptionRepair(baseSubscription.getId(), realRunBundleRepair);
+ assertEquals(bpRepair.getExistingEvents().size(), 3);
+
+ // STEPH BUG -- WE ONLY SEE THAT AFTER WE HIT DISK.
+ expectedAO.add(createExistingEventForAssertion(SubscriptionTransitionType.CANCEL, null, null,
+ ProductCategory.ADD_ON, null, null, newChargedThroughDate));
+ index = 0;
+ for (ExistingEvent e : expectedAO) {
+ validateExistingEventForAssertion(e, aoRepair.getExistingEvents().get(index++));
+ }
+
+ index = 0;
+ for (ExistingEvent e : expectedBP) {
+ validateExistingEventForAssertion(e, bpRepair.getExistingEvents().get(index++));
+ }
+
+ newAoSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(aoSubscription.getId());
+ assertEquals(newAoSubscription.getState(), SubscriptionState.ACTIVE);
+ assertEquals(newAoSubscription.getAllTransitions().size(), 3);
+ assertEquals(newAoSubscription.getActiveVersion(), SubscriptionEvents.INITIAL_VERSION + 1);
+
+ newBaseSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(baseSubscription.getId());
+ assertEquals(newBaseSubscription.getState(), SubscriptionState.ACTIVE);
+ assertEquals(newBaseSubscription.getAllTransitions().size(), 3);
+ assertEquals(newBaseSubscription.getActiveVersion(), SubscriptionEvents.INITIAL_VERSION + 1);
+
+ // MOVE CLOCK AFTER CANCEL DATE
+ testListener.pushExpectedEvent(NextEvent.CANCEL);
+ testListener.pushExpectedEvent(NextEvent.CANCEL);
+ someTimeLater = getDurationDay(32);
+ clock.addDeltaFromReality(someTimeLater);
+ assertTrue(testListener.isCompleted(7000));
+
+ newAoSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(aoSubscription.getId());
+ assertEquals(newAoSubscription.getState(), SubscriptionState.CANCELLED);
+ assertEquals(newAoSubscription.getAllTransitions().size(), 3);
+ assertEquals(newAoSubscription.getActiveVersion(), SubscriptionEvents.INITIAL_VERSION + 1);
+
+ newBaseSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(baseSubscription.getId());
+ assertEquals(newBaseSubscription.getState(), SubscriptionState.CANCELLED);
+ assertEquals(newBaseSubscription.getAllTransitions().size(), 3);
+ assertEquals(newBaseSubscription.getActiveVersion(), SubscriptionEvents.INITIAL_VERSION + 1);
}
@@ -126,7 +516,7 @@ public class TestRepairWithAO extends TestApiBaseRepair {
expected.add(createExistingEventForAssertion(SubscriptionTransitionType.CREATE, "Telescopic-Scope", PhaseType.DISCOUNT,
ProductCategory.ADD_ON, PriceListSet.DEFAULT_PRICELIST_NAME, BillingPeriod.MONTHLY, aoSubscription.getStartDate()));
expected.add(createExistingEventForAssertion(SubscriptionTransitionType.CANCEL, null, null,
- ProductCategory.ADD_ON, null, null, aoCancelDate));
+ ProductCategory.ADD_ON, null, null, aoCancelDate));
int index = 0;
for (ExistingEvent e : expected) {
validateExistingEventForAssertion(e, aoRepair.getExistingEvents().get(index++));
@@ -249,7 +639,7 @@ public class TestRepairWithAO extends TestApiBaseRepair {
//
// We are doing repair for multi-phase tiered-addon with different alignment:
// Telescopic-Scope -> Laser-Scope
- // Tiered ADON logix
+ // Tiered ADON logic
// . Both multi phase
// . Telescopic-Scope (bundle align) and Laser-Scope is Subscription align
//
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/repair/TestRepairWithError.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/repair/TestRepairWithError.java
index 87f3cea..4e67a53 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/repair/TestRepairWithError.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/repair/TestRepairWithError.java
@@ -43,6 +43,7 @@ import com.ning.billing.entitlement.api.repair.SubscriptionRepair.DeletedEvent;
import com.ning.billing.entitlement.api.repair.SubscriptionRepair.NewEvent;
import com.ning.billing.entitlement.api.user.EntitlementUserApiException;
import com.ning.billing.entitlement.api.user.Subscription;
+import com.ning.billing.entitlement.api.user.SubscriptionBundle;
import com.ning.billing.entitlement.api.user.SubscriptionData;
import com.ning.billing.entitlement.glue.MockEngineModuleMemory;
@@ -248,43 +249,180 @@ public class TestRepairWithError extends TestApiBaseRepair {
}, ErrorCode.ENT_REPAIR_AO_CREATE_BEFORE_BP_START);
}
- @Test(groups={"fast"}, enabled=false)
+ @Test(groups={"fast"})
public void testENT_REPAIR_NEW_EVENT_BEFORE_LAST_AO_REMAINING() throws Exception {
test.withException(new TestWithExceptionCallback() {
@Override
- public void doTest() throws EntitlementRepairException {
+ public void doTest() throws EntitlementRepairException, EntitlementUserApiException {
- }
- }, ErrorCode.ENT_REPAIR_NEW_EVENT_BEFORE_LAST_AO_REMAINING);
- }
- @Test(groups={"fast"}, enabled=false)
- public void testENT_REPAIR_MISSING_AO_DELETE_EVENT() throws Exception {
- test.withException(new TestWithExceptionCallback() {
- @Override
- public void doTest() throws EntitlementRepairException {
+ // MOVE CLOCK A LITTLE BIT-- STILL IN TRIAL
+ Duration someTimeLater = getDurationDay(3);
+ clock.setDeltaFromReality(someTimeLater, DAY_IN_MS);
+
+ SubscriptionData aoSubscription = createSubscription("Telescopic-Scope", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME);
+
+ // MOVE CLOCK A LITTLE BIT MORE -- STILL IN TRIAL
+ clock.addDeltaFromReality(someTimeLater);
+
+ BundleRepair bundleRepair = repairApi.getBundleRepair(bundle.getId());
+ sortEventsOnBundle(bundleRepair);
+
+ // Quick check
+ SubscriptionRepair bpRepair = getSubscriptionRepair(baseSubscription.getId(), bundleRepair);
+ assertEquals(bpRepair.getExistingEvents().size(), 2);
+
+ SubscriptionRepair aoRepair = getSubscriptionRepair(aoSubscription.getId(), bundleRepair);
+ assertEquals(aoRepair.getExistingEvents().size(), 2);
+
+
+ List<DeletedEvent> des = new LinkedList<SubscriptionRepair.DeletedEvent>();
+ //des.add(createDeletedEvent(aoRepair.getExistingEvents().get(1).getEventId()));
+ DateTime aoCancelDate = aoSubscription.getStartDate().plusDays(10);
+ NewEvent ne = createNewEvent(SubscriptionTransitionType.CANCEL, aoCancelDate, null);
+
+ SubscriptionRepair saoRepair = createSubscriptionReapir(aoSubscription.getId(), des, Collections.singletonList(ne));
+
+ bundleRepair = createBundleRepair(bundle.getId(), bundleRepair.getViewId(), Collections.singletonList(saoRepair));
+
+ boolean dryRun = true;
+ repairApi.repairBundle(bundleRepair, dryRun, context);
}
- }, ErrorCode.ENT_REPAIR_MISSING_AO_DELETE_EVENT);
+ }, ErrorCode.ENT_REPAIR_NEW_EVENT_BEFORE_LAST_AO_REMAINING);
}
- @Test(groups={"fast"}, enabled=false)
+
+ @Test(groups={"fast"})
public void testENT_REPAIR_BP_RECREATE_MISSING_AO() throws Exception {
test.withException(new TestWithExceptionCallback() {
@Override
- public void doTest() throws EntitlementRepairException {
+ public void doTest() throws EntitlementRepairException, EntitlementUserApiException {
+
+ //testListener.pushExpectedEvent(NextEvent.PHASE);
+
+ clock.setDeltaFromReality(getDurationDay(5), 0);
+ //assertTrue(testListener.isCompleted(5000));
+
+ SubscriptionData aoSubscription = createSubscription("Laser-Scope", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME);
+
+ BundleRepair bundleRepair = repairApi.getBundleRepair(bundle.getId());
+ sortEventsOnBundle(bundleRepair);
+
+ DateTime newCreateTime = baseSubscription.getStartDate().plusDays(3);
+
+ PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Pistol", ProductCategory.BASE, BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, PhaseType.TRIAL);
+
+ NewEvent ne = createNewEvent(SubscriptionTransitionType.CREATE, newCreateTime, spec);
+ List<DeletedEvent> des = new LinkedList<SubscriptionRepair.DeletedEvent>();
+ des.add(createDeletedEvent(bundleRepair.getSubscriptions().get(0).getExistingEvents().get(0).getEventId()));
+ des.add(createDeletedEvent(bundleRepair.getSubscriptions().get(0).getExistingEvents().get(1).getEventId()));
+
+ SubscriptionRepair sRepair = createSubscriptionReapir(baseSubscription.getId(), des, Collections.singletonList(ne));
+
+ // FIRST ISSUE DRY RUN
+ BundleRepair bRepair = createBundleRepair(bundle.getId(), bundleRepair.getViewId(), Collections.singletonList(sRepair));
+ boolean dryRun = true;
+ repairApi.repairBundle(bRepair, dryRun, context);
}
}, ErrorCode.ENT_REPAIR_BP_RECREATE_MISSING_AO);
}
+ //
+ // CAN'T seem to trigger such case easily, other errors trigger before...
+ //
@Test(groups={"fast"}, enabled=false)
public void testENT_REPAIR_BP_RECREATE_MISSING_AO_CREATE() throws Exception {
test.withException(new TestWithExceptionCallback() {
@Override
- public void doTest() throws EntitlementRepairException {
+ public void doTest() throws EntitlementRepairException, EntitlementUserApiException {
+ /*
+ //testListener.pushExpectedEvent(NextEvent.PHASE);
+
+ clock.setDeltaFromReality(getDurationDay(5), 0);
+ //assertTrue(testListener.isCompleted(5000));
+
+ SubscriptionData aoSubscription = createSubscription("Laser-Scope", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME);
+ BundleRepair bundleRepair = repairApi.getBundleRepair(bundle.getId());
+ sortEventsOnBundle(bundleRepair);
+
+ DateTime newCreateTime = baseSubscription.getStartDate().plusDays(3);
+
+ PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Pistol", ProductCategory.BASE, BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, PhaseType.TRIAL);
+
+ NewEvent ne = createNewEvent(SubscriptionTransitionType.CREATE, newCreateTime, spec);
+ List<DeletedEvent> des = new LinkedList<SubscriptionRepair.DeletedEvent>();
+ des.add(createDeletedEvent(bundleRepair.getSubscriptions().get(0).getExistingEvents().get(0).getEventId()));
+ des.add(createDeletedEvent(bundleRepair.getSubscriptions().get(0).getExistingEvents().get(1).getEventId()));
+
+ SubscriptionRepair bpRepair = createSubscriptionReapir(baseSubscription.getId(), des, Collections.singletonList(ne));
+
+ ne = createNewEvent(SubscriptionTransitionType.CANCEL, clock.getUTCNow().minusDays(1), null);
+ SubscriptionRepair aoRepair = createSubscriptionReapir(aoSubscription.getId(), Collections.<SubscriptionRepair.DeletedEvent>emptyList(), Collections.singletonList(ne));
+
+
+ List<SubscriptionRepair> allRepairs = new LinkedList<SubscriptionRepair>();
+ allRepairs.add(bpRepair);
+ allRepairs.add(aoRepair);
+ bundleRepair = createBundleRepair(bundle.getId(), bundleRepair.getViewId(), allRepairs);
+ // FIRST ISSUE DRY RUN
+ BundleRepair bRepair = createBundleRepair(bundle.getId(), bundleRepair.getViewId(), allRepairs);
+
+ boolean dryRun = true;
+ repairApi.repairBundle(bRepair, dryRun, context);
+ */
}
}, ErrorCode.ENT_REPAIR_BP_RECREATE_MISSING_AO_CREATE);
}
+
+ @Test(groups={"fast"}, enabled=false)
+ public void testENT_REPAIR_MISSING_AO_DELETE_EVENT() throws Exception {
+ test.withException(new TestWithExceptionCallback() {
+ @Override
+ public void doTest() throws EntitlementRepairException, EntitlementUserApiException {
+
+
+ /*
+ // MOVE CLOCK -- JUST BEFORE END OF TRIAL
+ clock.setDeltaFromReality(getDurationDay(29), 0);
+
+ SubscriptionData aoSubscription = createSubscription("Laser-Scope", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME);
+
+ // MOVE CLOCK -- RIGHT OUT OF TRIAL
+ testListener.pushExpectedEvent(NextEvent.PHASE);
+ clock.addDeltaFromReality(getDurationDay(5));
+ assertTrue(testListener.isCompleted(5000));
+
+ DateTime requestedChange = clock.getUTCNow();
+ baseSubscription.changePlan("Assault-Rifle", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, requestedChange, context);
+
+ DateTime reapairTime = clock.getUTCNow().minusDays(1);
+
+ BundleRepair bundleRepair = repairApi.getBundleRepair(bundle.getId());
+ sortEventsOnBundle(bundleRepair);
+
+ SubscriptionRepair bpRepair = getSubscriptionRepair(baseSubscription.getId(), bundleRepair);
+ SubscriptionRepair aoRepair = getSubscriptionRepair(aoSubscription.getId(), bundleRepair);
+
+ List<DeletedEvent> bpdes = new LinkedList<SubscriptionRepair.DeletedEvent>();
+ bpdes.add(createDeletedEvent(bpRepair.getExistingEvents().get(2).getEventId()));
+ bpRepair = createSubscriptionReapir(baseSubscription.getId(), bpdes, Collections.<NewEvent>emptyList());
+
+ NewEvent ne = createNewEvent(SubscriptionTransitionType.CANCEL, reapairTime, null);
+ aoRepair = createSubscriptionReapir(aoSubscription.getId(), Collections.<SubscriptionRepair.DeletedEvent>emptyList(), Collections.singletonList(ne));
+
+ List<SubscriptionRepair> allRepairs = new LinkedList<SubscriptionRepair>();
+ allRepairs.add(bpRepair);
+ allRepairs.add(aoRepair);
+ bundleRepair = createBundleRepair(bundle.getId(), bundleRepair.getViewId(), allRepairs);
+
+ boolean dryRun = false;
+ repairApi.repairBundle(bundleRepair, dryRun, context);
+ */
+ }
+ }, ErrorCode.ENT_REPAIR_MISSING_AO_DELETE_EVENT);
+ }
+
}