killbill-memoizeit

entitlement: fix bugs in BlockingState ordering Relates

1/15/2016 5:05:04 PM

Details

diff --git a/api/src/main/java/org/killbill/billing/junction/DefaultBlockingState.java b/api/src/main/java/org/killbill/billing/junction/DefaultBlockingState.java
index dd450d4..b548665 100644
--- a/api/src/main/java/org/killbill/billing/junction/DefaultBlockingState.java
+++ b/api/src/main/java/org/killbill/billing/junction/DefaultBlockingState.java
@@ -151,7 +151,7 @@ public class DefaultBlockingState extends EntityBase implements BlockingState {
         if (comparison == 0) {
             // Keep a stable ordering for ties
             final int comparison2 = createdDate.compareTo(arg0.getCreatedDate());
-            if (comparison2 == 0 && getClass() != arg0.getClass()) {
+            if (comparison2 == 0 && arg0 instanceof DefaultBlockingState) {
                 final DefaultBlockingState other = (DefaultBlockingState) arg0;
                 // New element is last
                 if (totalOrdering == null) {
diff --git a/entitlement/src/main/java/org/killbill/billing/entitlement/dao/ProxyBlockingStateDao.java b/entitlement/src/main/java/org/killbill/billing/entitlement/dao/ProxyBlockingStateDao.java
index 6a64cc7..1defc97 100644
--- a/entitlement/src/main/java/org/killbill/billing/entitlement/dao/ProxyBlockingStateDao.java
+++ b/entitlement/src/main/java/org/killbill/billing/entitlement/dao/ProxyBlockingStateDao.java
@@ -77,8 +77,11 @@ public class ProxyBlockingStateDao implements BlockingStateDao {
             final BlockingState current = iterator.next();
             if (iterator.hasNext()) {
                 final BlockingState next = iterator.next();
-                if (prev != null && current.getEffectiveDate().equals(next.getEffectiveDate()) && current.getBlockedId().equals(next.getBlockedId())) {
-                    // Same date, same blockable id
+                if (prev != null &&
+                    current.getEffectiveDate().equals(next.getEffectiveDate()) &&
+                    current.getBlockedId().equals(next.getBlockedId()) &&
+                    !current.getService().equals(next.getService())) {
+                    // Same date, same blockable id, different services (for same-service events, trust the total ordering)
 
                     // Make sure block billing transitions are respected first
                     BlockingState prevCandidate = insertTiedBlockingStatesInTheRightOrder(result, current, next, prev.isBlockBilling(), current.isBlockBilling(), next.isBlockBilling());
diff --git a/entitlement/src/test/java/org/killbill/billing/entitlement/dao/TestProxyBlockingStateDao.java b/entitlement/src/test/java/org/killbill/billing/entitlement/dao/TestProxyBlockingStateDao.java
new file mode 100644
index 0000000..549f02b
--- /dev/null
+++ b/entitlement/src/test/java/org/killbill/billing/entitlement/dao/TestProxyBlockingStateDao.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright 2016 Groupon, Inc
+ * Copyright 2016 The Billing Project, LLC
+ *
+ * The Billing Project licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.killbill.billing.entitlement.dao;
+
+import java.util.List;
+import java.util.UUID;
+
+import org.joda.time.DateTime;
+import org.killbill.billing.entitlement.EntitlementTestSuiteNoDB;
+import org.killbill.billing.entitlement.api.BlockingState;
+import org.killbill.billing.entitlement.api.BlockingStateType;
+import org.killbill.billing.junction.DefaultBlockingState;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import com.google.common.collect.ImmutableList;
+
+public class TestProxyBlockingStateDao extends EntitlementTestSuiteNoDB {
+
+    @Test(groups = "fast", description = "https://github.com/killbill/killbill/issues/174")
+    public void testComparisonSameEffectiveDate() throws Exception {
+        final UUID blockedId = UUID.randomUUID();
+        final BlockingStateType blockingStateType = BlockingStateType.ACCOUNT;
+        final String service = "test";
+        final DateTime effectiveDate = clock.getUTCNow();
+
+        final BlockingState bs1 = new DefaultBlockingState(UUID.randomUUID(),
+                                                           blockedId,
+                                                           blockingStateType,
+                                                           "OD1",
+                                                           service,
+                                                           false,
+                                                           false,
+                                                           false,
+                                                           effectiveDate.minusDays(10),
+                                                           effectiveDate,
+                                                           effectiveDate,
+                                                           1L);
+        final BlockingState bs2 = new DefaultBlockingState(UUID.randomUUID(),
+                                                           blockedId,
+                                                           blockingStateType,
+                                                           "OD2",
+                                                           service,
+                                                           true,
+                                                           true,
+                                                           true,
+                                                           effectiveDate.minusDays(5),
+                                                           effectiveDate,
+                                                           effectiveDate,
+                                                           2L);
+        final BlockingState bs3 = new DefaultBlockingState(UUID.randomUUID(),
+                                                           blockedId,
+                                                           blockingStateType,
+                                                           "OD3",
+                                                           service,
+                                                           true,
+                                                           true,
+                                                           true,
+                                                           effectiveDate,
+                                                           effectiveDate,
+                                                           effectiveDate,
+                                                           3L);
+        final BlockingState bs4 = new DefaultBlockingState(UUID.randomUUID(),
+                                                           blockedId,
+                                                           blockingStateType,
+                                                           DefaultBlockingState.CLEAR_STATE_NAME,
+                                                           service,
+                                                           false,
+                                                           false,
+                                                           false,
+                                                           effectiveDate,
+                                                           effectiveDate,
+                                                           effectiveDate,
+                                                           4L);
+
+        verifySortedCopy(bs1, bs2, bs3, bs4, bs1, bs2, bs3, bs4);
+        verifySortedCopy(bs1, bs2, bs3, bs4, bs1, bs3, bs2, bs4);
+        verifySortedCopy(bs1, bs2, bs3, bs4, bs2, bs3, bs1, bs4);
+        verifySortedCopy(bs1, bs2, bs3, bs4, bs2, bs1, bs3, bs4);
+        verifySortedCopy(bs1, bs2, bs3, bs4, bs3, bs1, bs2, bs4);
+        verifySortedCopy(bs1, bs2, bs3, bs4, bs3, bs2, bs1, bs4);
+    }
+
+    private void verifySortedCopy(final BlockingState bs1, final BlockingState bs2, final BlockingState bs3, final BlockingState bs4,
+                                  final BlockingState a, final BlockingState b, final BlockingState c, final BlockingState d) {
+        final List<BlockingState> sortedCopy = ProxyBlockingStateDao.sortedCopy(ImmutableList.<BlockingState>of(a, b, c, d));
+        Assert.assertEquals(sortedCopy.get(0).getStateName(), bs1.getStateName());
+        Assert.assertEquals(sortedCopy.get(1).getStateName(), bs2.getStateName());
+        Assert.assertEquals(sortedCopy.get(2).getStateName(), bs3.getStateName());
+        Assert.assertEquals(sortedCopy.get(3).getStateName(), bs4.getStateName());
+    }
+}
diff --git a/junction/src/test/java/org/killbill/billing/junction/TestDefaultBlockingState.java b/junction/src/test/java/org/killbill/billing/junction/TestDefaultBlockingState.java
new file mode 100644
index 0000000..2bc9e33
--- /dev/null
+++ b/junction/src/test/java/org/killbill/billing/junction/TestDefaultBlockingState.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2016 Groupon, Inc
+ * Copyright 2016 The Billing Project, LLC
+ *
+ * The Billing Project licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.killbill.billing.junction;
+
+import java.util.UUID;
+
+import org.joda.time.DateTime;
+import org.killbill.billing.entitlement.api.BlockingState;
+import org.killbill.billing.entitlement.api.BlockingStateType;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+public class TestDefaultBlockingState extends JunctionTestSuiteNoDB {
+
+    @Test(groups = "fast", description = "https://github.com/killbill/killbill/issues/174")
+    public void testComparisonSameEffectiveDate() throws Exception {
+        final DateTime effectiveDate = clock.getUTCNow();
+        final BlockingState bs1 = new DefaultBlockingState(UUID.randomUUID(),
+                                                           UUID.randomUUID(),
+                                                           BlockingStateType.ACCOUNT,
+                                                           "OD3",
+                                                           "test",
+                                                           true,
+                                                           true,
+                                                           true,
+                                                           effectiveDate,
+                                                           effectiveDate,
+                                                           effectiveDate,
+                                                           3L);
+        final BlockingState bs2 = new DefaultBlockingState(UUID.randomUUID(),
+                                                           UUID.randomUUID(),
+                                                           BlockingStateType.ACCOUNT,
+                                                           DefaultBlockingState.CLEAR_STATE_NAME,
+                                                           "test",
+                                                           false,
+                                                           false,
+                                                           false,
+                                                           effectiveDate,
+                                                           effectiveDate,
+                                                           effectiveDate,
+                                                           4L);
+        final BlockingState bs3 = new DefaultBlockingState(UUID.randomUUID(),
+                                                           UUID.randomUUID(),
+                                                           BlockingStateType.ACCOUNT,
+                                                           "OD1",
+                                                           "test",
+                                                           true,
+                                                           true,
+                                                           true,
+                                                           effectiveDate.plusMillis(1),
+                                                           effectiveDate,
+                                                           effectiveDate,
+                                                           5L);
+        Assert.assertTrue(bs1.compareTo(bs2) < 0);
+        Assert.assertTrue(bs1.compareTo(bs3) < 0);
+        Assert.assertTrue(bs2.compareTo(bs1) > 0);
+        Assert.assertTrue(bs2.compareTo(bs3) < 0);
+        Assert.assertTrue(bs3.compareTo(bs2) > 0);
+        Assert.assertTrue(bs3.compareTo(bs1) > 0);
+    }
+}