killbill-uncached

Details

diff --git a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/BeatrixIntegrationModule.java b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/BeatrixIntegrationModule.java
index 2c05cc1..eea3f8c 100644
--- a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/BeatrixIntegrationModule.java
+++ b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/BeatrixIntegrationModule.java
@@ -121,10 +121,7 @@ public class BeatrixIntegrationModule extends AbstractModule {
         install(new NonEntityDaoModule());
         install(new RecordIdModule());
         install(new BeatrixModuleWithSubsetLifecycle(configSource));
-
-
-        // STEPH_USAGE is that really what we want.
-        install(new TestUsageModule(configSource));
+        install(new UsageModule(configSource));
 
         bind(AccountChecker.class).asEagerSingleton();
         bind(SubscriptionChecker.class).asEagerSingleton();
diff --git a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/usage/TestConsumableInArrear.java b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/usage/TestConsumableInArrear.java
index b7ea0d7..84f8329 100644
--- a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/usage/TestConsumableInArrear.java
+++ b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/usage/TestConsumableInArrear.java
@@ -38,6 +38,7 @@ import org.killbill.billing.usage.api.RolledUpUsage;
 import org.killbill.billing.usage.api.UsageUserApi;
 import org.killbill.billing.usage.api.user.DefaultRolledUpUsage;
 import org.killbill.billing.usage.api.user.MockUsageUserApi;
+import org.killbill.billing.util.callcontext.CallContext;
 import org.killbill.billing.util.callcontext.TenantContext;
 import org.mockito.Mockito;
 import org.testng.annotations.BeforeMethod;
@@ -82,13 +83,10 @@ public class TestConsumableInArrear extends TestIntegrationBase {
         //
         // ADD ADD_ON ON THE SAME DAY
         //
-        final List<RolledUpUsage> usageList = new ArrayList<RolledUpUsage>();
-        setUsage(usageList);
-        addAOEntitlementAndCheckForCompletion(bpSubscription.getBundleId(), "Bullets", ProductCategory.ADD_ON, BillingPeriod.NO_BILLING_PERIOD, NextEvent.CREATE);
+        final DefaultEntitlement aoSubscription = addAOEntitlementAndCheckForCompletion(bpSubscription.getBundleId(), "Bullets", ProductCategory.ADD_ON, BillingPeriod.NO_BILLING_PERIOD, NextEvent.CREATE);
 
-        RolledUpUsage usage1 = new DefaultRolledUpUsage(UUID.randomUUID(), "bullets", new LocalDate(2012, 4, 1).toDateTimeAtStartOfDay(DateTimeZone.UTC), new LocalDate(2012, 5, 1).toDateTimeAtStartOfDay(DateTimeZone.UTC), new BigDecimal("199"));
-        usageList.add(usage1);
-        setUsage(usageList);
+        setUsage(aoSubscription.getId(), "bullets", new DateTime(2012, 4, 1, 1, 1, DateTimeZone.UTC), new DateTime(2012, 4, 15, 0, 0, DateTimeZone.UTC), new BigDecimal("99"), callContext);
+        setUsage(aoSubscription.getId(), "bullets", new DateTime(2012, 4, 15, 0, 0, DateTimeZone.UTC), new DateTime(2012, 4, 20, 1, 1, DateTimeZone.UTC), new BigDecimal("100"), callContext);
 
         busHandler.pushExpectedEvents(NextEvent.PHASE, NextEvent.INVOICE, NextEvent.PAYMENT);
         clock.setDay(new LocalDate(2012, 5, 1));
@@ -99,11 +97,6 @@ public class TestConsumableInArrear extends TestIntegrationBase {
                                     new ExpectedInvoiceItemCheck(new LocalDate(2012, 4, 1), new LocalDate(2012, 5, 1), InvoiceItemType.USAGE, new BigDecimal("5.90")));
 
 
-        // No usage for that period, we should still be schedule
-        RolledUpUsage usage2 = new DefaultRolledUpUsage(UUID.randomUUID(), "bullets", new LocalDate(2012, 5, 1).toDateTimeAtStartOfDay(DateTimeZone.UTC), new LocalDate(2012, 6, 1).toDateTimeAtStartOfDay(DateTimeZone.UTC), new BigDecimal("0"));
-        usageList.add(usage2);
-        setUsage(usageList);
-
         busHandler.pushExpectedEvents(NextEvent.INVOICE);
         clock.setDay(new LocalDate(2012, 6, 1));
         assertListenerStatus();
@@ -112,9 +105,9 @@ public class TestConsumableInArrear extends TestIntegrationBase {
                                     new ExpectedInvoiceItemCheck(new LocalDate(2012, 5, 1), new LocalDate(2012, 6, 1), InvoiceItemType.USAGE, BigDecimal.ZERO));
 
 
-        RolledUpUsage usage3 = new DefaultRolledUpUsage(UUID.randomUUID(), "bullets", new LocalDate(2012, 6, 1).toDateTimeAtStartOfDay(DateTimeZone.UTC), new LocalDate(2012, 7, 1).toDateTimeAtStartOfDay(DateTimeZone.UTC), new BigDecimal("350"));
-        usageList.add(usage3);
-        setUsage(usageList);
+        setUsage(aoSubscription.getId(), "bullets", new DateTime(2012, 6, 1, 1, 1, DateTimeZone.UTC), new DateTime(2012, 6, 15, 1, 1, DateTimeZone.UTC), new BigDecimal("50"), callContext);
+        setUsage(aoSubscription.getId(), "bullets", new DateTime(2012, 6, 16, 1, 1, DateTimeZone.UTC), new DateTime(2012, 6, 20, 1, 1, DateTimeZone.UTC), new BigDecimal("300"), callContext);
+
 
         busHandler.pushExpectedEvents(NextEvent.INVOICE, NextEvent.PAYMENT);
         clock.setDay(new LocalDate(2012, 7, 1));
@@ -125,7 +118,7 @@ public class TestConsumableInArrear extends TestIntegrationBase {
 
     }
 
-    private void setUsage(final List<RolledUpUsage> usageList) {
-        ((MockUsageUserApi) usageUserApi).setAllUsageForSubscription(usageList);
+    private void setUsage(final UUID subscriptionId, final String unitType, final DateTime startTime, final DateTime endTime, final BigDecimal amount, final CallContext context) {
+        usageUserApi.recordRolledUpUsage(subscriptionId, unitType, startTime, endTime, amount, context);
     }
 }
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/usage/ContiguousIntervalConsumableInArrear.java b/invoice/src/main/java/org/killbill/billing/invoice/usage/ContiguousIntervalConsumableInArrear.java
index 2ee9459..a45875f 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/usage/ContiguousIntervalConsumableInArrear.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/usage/ContiguousIntervalConsumableInArrear.java
@@ -377,7 +377,7 @@ public class ContiguousIntervalConsumableInArrear {
     }
 
     static DateTime localDateToEndOfDayInAccountTimezone(final LocalDate input, final DateTimeZone accountTimeZone) {
-        final DateTime dateTimeInAccountTimeZone = new DateTime(input.getYear(), input.getMonthOfYear(), input.getDayOfMonth(), 23, 59, 59, accountTimeZone);
+        final DateTime dateTimeInAccountTimeZone = new DateTime(input.getYear(), input.getMonthOfYear(), input.getDayOfMonth(), 0, 0, 0, accountTimeZone);
         return new DateTime(dateTimeInAccountTimeZone, DateTimeZone.UTC);
     }
 
diff --git a/usage/src/main/java/org/killbill/billing/usage/api/user/DefaultUsageUserApi.java b/usage/src/main/java/org/killbill/billing/usage/api/user/DefaultUsageUserApi.java
index c685257..5b771d9 100644
--- a/usage/src/main/java/org/killbill/billing/usage/api/user/DefaultUsageUserApi.java
+++ b/usage/src/main/java/org/killbill/billing/usage/api/user/DefaultUsageUserApi.java
@@ -17,6 +17,7 @@
 package org.killbill.billing.usage.api.user;
 
 import java.math.BigDecimal;
+import java.util.ArrayList;
 import java.util.List;
 import java.util.Set;
 import java.util.UUID;
@@ -26,6 +27,7 @@ import javax.inject.Inject;
 import org.joda.time.DateTime;
 
 import org.killbill.billing.ObjectType;
+import org.killbill.billing.callcontext.InternalTenantContext;
 import org.killbill.billing.usage.api.RolledUpUsage;
 import org.killbill.billing.usage.api.UsageUserApi;
 import org.killbill.billing.usage.dao.RolledUpUsageDao;
@@ -56,14 +58,25 @@ public class DefaultUsageUserApi implements UsageUserApi {
 
     @Override
     public RolledUpUsage getUsageForSubscription(final UUID subscriptionId,  final String unitType, final DateTime startTime, final DateTime endTime, final TenantContext context) {
-        final RolledUpUsageModelDao usageForSubscription = rolledUpUsageDao.getUsageForSubscription(subscriptionId, internalCallContextFactory.createInternalTenantContext(context));
+        final RolledUpUsageModelDao usageForSubscription = rolledUpUsageDao.getUsageForSubscription(subscriptionId, startTime, endTime, unitType, internalCallContextFactory.createInternalTenantContext(context));
         return new DefaultRolledUpUsage(usageForSubscription);
     }
 
     @Override
     public List<RolledUpUsage> getAllUsageForSubscription(final UUID subscriptionId, final Set<String> unitTypes, final List<DateTime> transitionTimes, final TenantContext tenantContext) {
-        // STEPH_USAGE implement
-        // STEPH_USAGE also dates should be inclusive/exclusive so as to not bill twice for last day
-        return null;
+
+        final InternalTenantContext internalCallContext = internalCallContextFactory.createInternalTenantContext(subscriptionId, ObjectType.SUBSCRIPTION, tenantContext);
+        List<RolledUpUsage> result = new ArrayList<RolledUpUsage>();
+        DateTime prevDate = null;
+        for (DateTime curDate : transitionTimes) {
+            if (prevDate != null) {
+                for (String unitType : unitTypes) {
+                    final RolledUpUsageModelDao usageForSubscription = rolledUpUsageDao.getUsageForSubscription(subscriptionId, prevDate, curDate, unitType, internalCallContext);
+                    result.add(new DefaultRolledUpUsage(usageForSubscription));
+                }
+            }
+            prevDate = curDate;
+        }
+        return result;
     }
 }
diff --git a/usage/src/main/java/org/killbill/billing/usage/dao/DefaultRolledUpUsageDao.java b/usage/src/main/java/org/killbill/billing/usage/dao/DefaultRolledUpUsageDao.java
index 353a799..9c190c8 100644
--- a/usage/src/main/java/org/killbill/billing/usage/dao/DefaultRolledUpUsageDao.java
+++ b/usage/src/main/java/org/killbill/billing/usage/dao/DefaultRolledUpUsageDao.java
@@ -17,11 +17,15 @@
 package org.killbill.billing.usage.dao;
 
 import java.math.BigDecimal;
+import java.util.List;
+import java.util.Set;
 import java.util.UUID;
 
 import javax.inject.Inject;
 
 import org.joda.time.DateTime;
+import org.killbill.billing.usage.api.RolledUpUsage;
+import org.killbill.billing.util.callcontext.TenantContext;
 import org.skife.jdbi.v2.IDBI;
 
 import org.killbill.billing.callcontext.InternalCallContext;
@@ -46,7 +50,8 @@ public class DefaultRolledUpUsageDao implements RolledUpUsageDao {
     }
 
     @Override
-    public RolledUpUsageModelDao getUsageForSubscription(final UUID subscriptionId, final InternalTenantContext context) {
-        return rolledUpUsageSqlDao.getUsageForSubscription(subscriptionId, context);
+    public RolledUpUsageModelDao getUsageForSubscription(UUID subscriptionId, DateTime startTime, DateTime endTime, String unitType, InternalTenantContext context) {
+        final BigDecimal amount = rolledUpUsageSqlDao.getUsageForSubscription(subscriptionId, startTime.toDate(), endTime.toDate(), unitType, context);
+        return new RolledUpUsageModelDao(subscriptionId, unitType, startTime, endTime, amount != null ? amount : BigDecimal.ZERO);
     }
 }
diff --git a/usage/src/main/java/org/killbill/billing/usage/dao/RolledUpUsageDao.java b/usage/src/main/java/org/killbill/billing/usage/dao/RolledUpUsageDao.java
index e0b90a1..225b3c8 100644
--- a/usage/src/main/java/org/killbill/billing/usage/dao/RolledUpUsageDao.java
+++ b/usage/src/main/java/org/killbill/billing/usage/dao/RolledUpUsageDao.java
@@ -17,17 +17,21 @@
 package org.killbill.billing.usage.dao;
 
 import java.math.BigDecimal;
+import java.util.List;
+import java.util.Set;
 import java.util.UUID;
 
 import org.joda.time.DateTime;
 
 import org.killbill.billing.callcontext.InternalCallContext;
 import org.killbill.billing.callcontext.InternalTenantContext;
+import org.killbill.billing.usage.api.RolledUpUsage;
+import org.killbill.billing.util.callcontext.TenantContext;
 
 public interface RolledUpUsageDao {
 
     void record(UUID subscriptionId, String unitType, DateTime startTime,
                 DateTime endTime, BigDecimal amount, InternalCallContext context);
 
-    RolledUpUsageModelDao getUsageForSubscription(UUID subscriptionId, InternalTenantContext context);
+    RolledUpUsageModelDao getUsageForSubscription(UUID subscriptionId, DateTime startTime, DateTime endTime, String unitType, InternalTenantContext context);
 }
diff --git a/usage/src/main/java/org/killbill/billing/usage/dao/RolledUpUsageSqlDao.java b/usage/src/main/java/org/killbill/billing/usage/dao/RolledUpUsageSqlDao.java
index 29042ca..4bfdb8a 100644
--- a/usage/src/main/java/org/killbill/billing/usage/dao/RolledUpUsageSqlDao.java
+++ b/usage/src/main/java/org/killbill/billing/usage/dao/RolledUpUsageSqlDao.java
@@ -16,6 +16,8 @@
 
 package org.killbill.billing.usage.dao;
 
+import java.math.BigDecimal;
+import java.util.Date;
 import java.util.UUID;
 
 import org.skife.jdbi.v2.sqlobject.Bind;
@@ -36,6 +38,9 @@ public interface RolledUpUsageSqlDao {
                        @InternalTenantContextBinder final InternalCallContext context);
 
     @SqlQuery
-    public RolledUpUsageModelDao getUsageForSubscription(@Bind("subscriptionId") final UUID subscriptionId,
+    public BigDecimal getUsageForSubscription(@Bind("subscriptionId") final UUID subscriptionId,
+                                                         @Bind("startTime") final Date startTime,
+                                                         @Bind("endTime") final Date endTime,
+                                                         @Bind("unitType") final String unitType,
                                                          @InternalTenantContextBinder final InternalTenantContext context);
 }
diff --git a/usage/src/main/resources/org/killbill/billing/usage/dao/RolledUpUsageSqlDao.sql.stg b/usage/src/main/resources/org/killbill/billing/usage/dao/RolledUpUsageSqlDao.sql.stg
index e028757..431d976 100644
--- a/usage/src/main/resources/org/killbill/billing/usage/dao/RolledUpUsageSqlDao.sql.stg
+++ b/usage/src/main/resources/org/killbill/billing/usage/dao/RolledUpUsageSqlDao.sql.stg
@@ -1,6 +1,6 @@
-group RolledUpUsageSqlDao;
+group RolledUpUsageSqlDao: EntitySqlDao;
 
-tableName() ::= "usage"
+tableName() ::= "rolled_up_usage"
 
 tableFields(prefix) ::= <<
   <prefix>id
@@ -43,9 +43,13 @@ values (
 
 getUsageForSubscription() ::= <<
 select
-  <tableFields("t.")>
+  sum(amount)
 from <tableName()> t
 where subscription_id = :subscriptionId
+and start_time >= :startTime
+and end_time \<= :endTime
+and unit_type = :unitType
 <AND_CHECK_TENANT()>
 ;
 >>
+
diff --git a/usage/src/main/resources/org/killbill/billing/usage/ddl.sql b/usage/src/main/resources/org/killbill/billing/usage/ddl.sql
index aa1bd96..2d8edc9 100644
--- a/usage/src/main/resources/org/killbill/billing/usage/ddl.sql
+++ b/usage/src/main/resources/org/killbill/billing/usage/ddl.sql
@@ -6,9 +6,9 @@ CREATE TABLE rolled_up_usage (
     id char(36) NOT NULL,
     subscription_id char(36),
     unit_type varchar(50),
-    start_date date NOT NULL,
-    end_date date,
-    amount numeric(10,10) NOT NULL,
+    start_time datetime NOT NULL,
+    end_time datetime,
+    amount decimal(15,9) NOT NULL,
     created_by varchar(50) NOT NULL,
     created_date datetime NOT NULL,
     account_record_id int(11) unsigned default null,
diff --git a/usage/src/test/java/org/killbill/billing/usage/dao/TestDefaultRolledUpUsageDao.java b/usage/src/test/java/org/killbill/billing/usage/dao/TestDefaultRolledUpUsageDao.java
new file mode 100644
index 0000000..e83e33a
--- /dev/null
+++ b/usage/src/test/java/org/killbill/billing/usage/dao/TestDefaultRolledUpUsageDao.java
@@ -0,0 +1,59 @@
+package org.killbill.billing.usage.dao;
+
+import java.math.BigDecimal;
+import java.util.UUID;
+
+import org.joda.time.DateTime;
+import org.joda.time.DateTimeZone;
+import org.killbill.billing.usage.UsageTestSuiteWithEmbeddedDB;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+
+public class TestDefaultRolledUpUsageDao extends UsageTestSuiteWithEmbeddedDB {
+
+    @BeforeMethod(groups = "slow")
+    public void setUp() throws Exception {
+    }
+
+    @Test(groups = "slow")
+    public void testSimple() {
+        final UUID subscriptionId = UUID.randomUUID();
+        final String unitType = "foo";
+        final DateTime startDate = new DateTime(2013, 1, 1, 0, 0, DateTimeZone.UTC);
+        final DateTime endDate = new DateTime(2013, 2, 1, 0, 0, DateTimeZone.UTC);
+        final BigDecimal amount1 = BigDecimal.TEN;
+        final BigDecimal amount2 = BigDecimal.TEN;
+
+        rolledUpUsageDao.record(subscriptionId, unitType, startDate, endDate, amount1, internalCallContext);
+        rolledUpUsageDao.record(subscriptionId, unitType, startDate, endDate, amount2, internalCallContext);
+
+        final RolledUpUsageModelDao result = rolledUpUsageDao.getUsageForSubscription(subscriptionId, startDate, endDate, unitType, internalCallContext);
+        assertEquals(result.getSubscriptionId(), subscriptionId);
+        assertEquals(result.getStartTime().compareTo(startDate), 0);
+        assertEquals(result.getEndTime().compareTo(endDate), 0);
+        assertEquals(result.getUnitType(), unitType);
+        assertEquals(result.getSubscriptionId(), subscriptionId);
+        assertEquals(result.getSubscriptionId(), subscriptionId);
+        assertEquals(result.getAmount().compareTo(amount1.add(amount2)), 0);
+    }
+
+    @Test(groups = "slow")
+    public void testNoEntries() {
+        final UUID subscriptionId = UUID.randomUUID();
+        final String unitType = "foo";
+        final DateTime startDate = new DateTime(2013, 1, 1, 0, 0, DateTimeZone.UTC);
+        final DateTime endDate = new DateTime(2013, 2, 1, 0, 0, DateTimeZone.UTC);
+
+        final RolledUpUsageModelDao result = rolledUpUsageDao.getUsageForSubscription(subscriptionId, startDate, endDate, unitType, internalCallContext);
+        assertEquals(result.getSubscriptionId(), subscriptionId);
+        assertEquals(result.getStartTime().compareTo(startDate), 0);
+        assertEquals(result.getEndTime().compareTo(endDate), 0);
+        assertEquals(result.getUnitType(), unitType);
+        assertEquals(result.getSubscriptionId(), subscriptionId);
+        assertEquals(result.getSubscriptionId(), subscriptionId);
+        assertEquals(result.getAmount().compareTo(BigDecimal.ZERO), 0);
+    }
+
+}
diff --git a/usage/src/test/java/org/killbill/billing/usage/UsageTestSuiteWithEmbeddedDB.java b/usage/src/test/java/org/killbill/billing/usage/UsageTestSuiteWithEmbeddedDB.java
index 9126e99..9ab15ff 100644
--- a/usage/src/test/java/org/killbill/billing/usage/UsageTestSuiteWithEmbeddedDB.java
+++ b/usage/src/test/java/org/killbill/billing/usage/UsageTestSuiteWithEmbeddedDB.java
@@ -16,6 +16,9 @@
 
 package org.killbill.billing.usage;
 
+import javax.inject.Inject;
+
+import org.killbill.billing.usage.dao.RolledUpUsageDao;
 import org.testng.annotations.AfterMethod;
 import org.testng.annotations.BeforeClass;
 import org.testng.annotations.BeforeMethod;
@@ -28,6 +31,9 @@ import com.google.inject.Injector;
 
 public class UsageTestSuiteWithEmbeddedDB extends GuicyKillbillTestSuiteWithEmbeddedDB {
 
+    @Inject
+    protected RolledUpUsageDao rolledUpUsageDao;
+
     @BeforeClass(groups = "slow")
     protected void beforeClass() throws Exception {
         final Injector injector = Guice.createInjector(new TestUsageModuleWithEmbeddedDB(configSource));