killbill-aplcache

Details

diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/AuditedEntitlementDao.java b/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/AuditedEntitlementDao.java
index ab0cd11..e8c3d2e 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/AuditedEntitlementDao.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/AuditedEntitlementDao.java
@@ -170,7 +170,7 @@ public class AuditedEntitlementDao implements EntitlementDao {
 
     @Override
     public List<Subscription> getSubscriptions(final SubscriptionFactory factory, final UUID bundleId) {
-        return buildBundleSubscriptions(factory, subscriptionsDao.getSubscriptionsFromBundleId(bundleId.toString()));
+        return buildBundleSubscriptions(bundleId, factory, subscriptionsDao.getSubscriptionsFromBundleId(bundleId.toString()));
     }
 
     @Override
@@ -493,7 +493,7 @@ public class AuditedEntitlementDao implements EntitlementDao {
             bundleInput.add(input);
         }
 
-        final List<Subscription> reloadedSubscriptions = buildBundleSubscriptions(factory, bundleInput);
+        final List<Subscription> reloadedSubscriptions = buildBundleSubscriptions(input.getBundleId(), factory, bundleInput);
         for (final Subscription cur : reloadedSubscriptions) {
             if (cur.getId().equals(input.getId())) {
                 return cur;
@@ -503,7 +503,7 @@ public class AuditedEntitlementDao implements EntitlementDao {
         throw new EntitlementError("Unexpected code path in buildSubscription");
     }
 
-    private List<Subscription> buildBundleSubscriptions(final SubscriptionFactory factory, final List<Subscription> input) {
+    private List<Subscription> buildBundleSubscriptions(final UUID bundleId, final SubscriptionFactory factory, final List<Subscription> input) {
         if (input == null || input.size() == 0) {
             return Collections.emptyList();
         }
@@ -512,6 +512,18 @@ public class AuditedEntitlementDao implements EntitlementDao {
         Collections.sort(input, new Comparator<Subscription>() {
             @Override
             public int compare(final Subscription o1, final Subscription o2) {
+
+                //
+                // STEPH production NPE needs debugging:
+                //
+                if (o1 == null) {
+                    log.error("o1 :Unexpected null subscription in compareMethod for bundle {}, input.size() = {}", bundleId, input.size());
+                }
+                if (o2 == null) {
+                    log.error("o2 :Unexpected null subscription in compareMethod for bundle {}, input.size() = {}", bundleId, input.size());
+                }
+
+
                 if (o1.getCategory() == ProductCategory.BASE) {
                     return -1;
                 } else if (o2.getCategory() == ProductCategory.BASE) {
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 069a325..c9f2681 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
@@ -64,6 +64,20 @@ public class RepairEntitlementDao implements EntitlementDao, RepairEntitlementLi
             return orderingId;
         }
 
+        @Override
+        public String toString() {
+            StringBuilder tmp  = new StringBuilder();
+            tmp.append("[");
+            tmp.append(event.getType());
+            tmp.append(": effDate=");
+            tmp.append(event.getEffectiveDate());
+            tmp.append(", subId=");
+            tmp.append(event.getSubscriptionId());
+            tmp.append(", ordering=");
+            tmp.append(event.getTotalOrdering());
+            tmp.append("]");
+            return tmp.toString();
+        }
     }
 
     private static final class SubscriptionRepairEvent {
@@ -82,7 +96,7 @@ public class RepairEntitlementDao implements EntitlementDao, RepairEntitlementLi
                         } else if (o1.getOrderingId() > o2.getOrderingId()) {
                             return 1;
                         } else {
-                            throw new RuntimeException("Repair entitlement events should not have the same orderingId");
+                            throw new RuntimeException(String.format(" Repair entitlement events should not have the same orderingId %s, %s ", o1, o2));
                         }
                     }
                     return result;
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/timeline/TestRepairBP.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/timeline/TestRepairBP.java
index 6ff4c51..e57df9b 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/timeline/TestRepairBP.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/timeline/TestRepairBP.java
@@ -692,6 +692,10 @@ public class TestRepairBP extends TestApiBaseRepair {
                 final BundleTimeline bRepair = createBundleRepair(bundle.getId(), bundleRepair.getViewId(), Collections.singletonList(sRepair));
 
                 final DateTime newChargedThroughDate = baseSubscription.getStartDate().plusDays(30).plusMonths(1);
+
+                // Move clock at least a sec to make sure the last_sys_update from bundle is different-- and therefore generates a different viewId
+                clock.setDeltaFromReality(1000);
+
                 billingApi.setChargedThroughDate(baseSubscription.getId(), newChargedThroughDate, context);
                 entitlementApi.getSubscriptionFromId(baseSubscription.getId());