killbill-uncached

Initial usage consumable in arrear beatrix test Fix two issues

3/23/2014 11:43:03 PM

Changes

beatrix/pom.xml 6(+6 -0)

Details

diff --git a/.idea/copyright/apache.xml b/.idea/copyright/apache.xml
index d5736cd..acd508f 100644
--- a/.idea/copyright/apache.xml
+++ b/.idea/copyright/apache.xml
@@ -1,6 +1,6 @@
 <component name="CopyrightManager">
   <copyright>
-    <option name="notice" value="Copyright 2010-&amp;#36;today.year Ning, Inc.&#10;&#10;Ning licenses this file to you under the Apache License, version 2.0&#10;(the &quot;License&quot;); you may not use this file except in compliance with the&#10;License.  You may obtain a copy of the License at:&#10;&#10;   http://www.apache.org/licenses/LICENSE-2.0&#10;&#10;Unless required by applicable law or agreed to in writing, software&#10;distributed under the License is distributed on an &quot;AS IS&quot; BASIS, WITHOUT&#10;WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the&#10;License for the specific language governing permissions and limitations&#10;under the License." />
+    <option name="notice" value="Copyright &amp;#36;today.year The Billing Project, LLC&#10;&#10;Ning licenses this file to you under the Apache License, version 2.0&#10;(the &quot;License&quot;); you may not use this file except in compliance with the&#10;License.  You may obtain a copy of the License at:&#10;&#10;   http://www.apache.org/licenses/LICENSE-2.0&#10;&#10;Unless required by applicable law or agreed to in writing, software&#10;distributed under the License is distributed on an &quot;AS IS&quot; BASIS, WITHOUT&#10;WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the&#10;License for the specific language governing permissions and limitations&#10;under the License." />
     <option name="keyword" value="Copyright" />
     <option name="allowReplaceKeyword" value="" />
     <option name="myName" value="apache" />

beatrix/pom.xml 6(+6 -0)

diff --git a/beatrix/pom.xml b/beatrix/pom.xml
index bb704d7..b1b166c 100644
--- a/beatrix/pom.xml
+++ b/beatrix/pom.xml
@@ -173,6 +173,12 @@
         </dependency>
         <dependency>
             <groupId>org.kill-bill.billing</groupId>
+            <artifactId>killbill-usage</artifactId>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.kill-bill.billing</groupId>
             <artifactId>killbill-util</artifactId>
             <type>test-jar</type>
             <scope>test</scope>
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 71571d8..2c05cc1 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
@@ -54,6 +54,7 @@ import org.killbill.billing.payment.provider.MockPaymentProviderPluginModule;
 import org.killbill.billing.subscription.api.SubscriptionBaseService;
 import org.killbill.billing.subscription.glue.DefaultSubscriptionModule;
 import org.killbill.billing.tenant.glue.TenantModule;
+import org.killbill.billing.usage.glue.TestUsageModule;
 import org.killbill.billing.usage.glue.UsageModule;
 import org.killbill.billing.util.config.PaymentConfig;
 import org.killbill.billing.util.email.EmailModule;
@@ -114,7 +115,6 @@ public class BeatrixIntegrationModule extends AbstractModule {
         install(new IntegrationTestOverdueModule(configSource));
         install(new AuditModule());
         install(new CurrencyModule(configSource));
-        install(new UsageModule(configSource));
         install(new TenantModule(configSource));
         install(new ExportModule());
         install(new DefaultOSGIModule(configSource));
@@ -122,6 +122,10 @@ public class BeatrixIntegrationModule extends AbstractModule {
         install(new RecordIdModule());
         install(new BeatrixModuleWithSubsetLifecycle(configSource));
 
+
+        // STEPH_USAGE is that really what we want.
+        install(new TestUsageModule(configSource));
+
         bind(AccountChecker.class).asEagerSingleton();
         bind(SubscriptionChecker.class).asEagerSingleton();
         bind(InvoiceChecker.class).asEagerSingleton();
diff --git a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestIntegrationBase.java b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestIntegrationBase.java
index 4f52701..3a14ae9 100644
--- a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestIntegrationBase.java
+++ b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestIntegrationBase.java
@@ -29,6 +29,7 @@ import javax.inject.Named;
 import org.joda.time.DateTime;
 import org.joda.time.DateTimeZone;
 import org.joda.time.LocalDate;
+import org.killbill.billing.usage.api.UsageUserApi;
 import org.skife.jdbi.v2.IDBI;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -188,6 +189,9 @@ public class TestIntegrationBase extends BeatrixTestSuiteWithEmbeddedDB {
     protected AccountInternalApi accountInternalApi;
 
     @Inject
+    protected UsageUserApi usageUserApi;
+
+    @Inject
     protected OSGIConfig osgiConfig;
 
     @Inject
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
new file mode 100644
index 0000000..4cce354
--- /dev/null
+++ b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/usage/TestConsumableInArrear.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright 2014 The Billing Project, LLC
+ *
+ * Ning 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.beatrix.integration.usage;
+
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+import java.util.UUID;
+
+import org.joda.time.DateTime;
+import org.joda.time.DateTimeZone;
+import org.joda.time.LocalDate;
+import org.killbill.billing.account.api.Account;
+import org.killbill.billing.account.api.AccountData;
+import org.killbill.billing.api.TestApiListener.NextEvent;
+import org.killbill.billing.beatrix.integration.TestIntegrationBase;
+import org.killbill.billing.beatrix.util.InvoiceChecker.ExpectedInvoiceItemCheck;
+import org.killbill.billing.catalog.api.BillingPeriod;
+import org.killbill.billing.catalog.api.ProductCategory;
+import org.killbill.billing.entitlement.api.DefaultEntitlement;
+import org.killbill.billing.invoice.api.InvoiceItemType;
+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.TenantContext;
+import org.mockito.Mockito;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import com.google.common.collect.ImmutableList;
+
+public class TestConsumableInArrear extends TestIntegrationBase {
+
+    @BeforeMethod(groups = "slow")
+    public void beforeMethod() throws Exception {
+        super.beforeMethod();
+    }
+
+    protected UsageUserApi createMockUsageUserApi(final List<RolledUpUsage> returnValue) {
+        final UsageUserApi result = Mockito.mock(UsageUserApi.class);
+        Mockito.when(result.getAllUsageForSubscription(Mockito.<UUID>any(), Mockito.<Set<String>>any(), Mockito.<List<DateTime>>any(), Mockito.<TenantContext>any())).thenReturn(returnValue);
+        return result;
+    }
+
+    @Test(groups = "slow")
+    public void testSimple() throws Exception {
+
+
+        final AccountData accountData = getAccountData(1);
+        final Account account = createAccountWithNonOsgiPaymentMethod(accountData);
+        accountChecker.checkAccount(account.getId(), accountData, callContext);
+
+        // We take april as it has 30 days (easier to play with BCD)
+        // Set clock to the initial start date - we implicitly assume here that the account timezone is UTC
+        clock.setDay(new LocalDate(2012, 4, 1));
+
+        //
+        // CREATE SUBSCRIPTION AND EXPECT BOTH EVENTS: NextEvent.CREATE NextEvent.INVOICE
+        //
+        final DefaultEntitlement bpSubscription = createBaseEntitlementAndCheckForCompletion(account.getId(), "bundleKey", "Shotgun", ProductCategory.BASE, BillingPeriod.MONTHLY, NextEvent.CREATE, NextEvent.INVOICE);
+        // Check bundle after BP got created otherwise we get an error from auditApi.
+        subscriptionChecker.checkSubscriptionCreated(bpSubscription.getId(), internalCallContext);
+        invoiceChecker.checkInvoice(account.getId(), 1, callContext, new ExpectedInvoiceItemCheck(new LocalDate(2012, 4, 1), null, InvoiceItemType.FIXED, new BigDecimal("0")));
+
+
+        //
+        // ADD ADD_ON ON THE SAME DAY
+        //
+        setUsage();
+        addAOEntitlementAndCheckForCompletion(bpSubscription.getBundleId(), "Bullets", ProductCategory.ADD_ON, BillingPeriod.NO_BILLING_PERIOD, NextEvent.CREATE);
+
+        final RolledUpUsage usage = new DefaultRolledUpUsage(UUID.randomUUID(), "bullets", new LocalDate(2012, 4, 1).toDateTimeAtStartOfDay(DateTimeZone.UTC), new LocalDate(2012, 5, 1).toDateTimeAtStartOfDay(DateTimeZone.UTC), new BigDecimal("199"));
+        setUsage(usage);
+
+        busHandler.pushExpectedEvents(NextEvent.PHASE, NextEvent.INVOICE, NextEvent.PAYMENT);
+        clock.setDay(new LocalDate(2012, 5, 1));
+        assertListenerStatus();
+
+        invoiceChecker.checkInvoice(account.getId(), 2, callContext,
+                                    new ExpectedInvoiceItemCheck(new LocalDate(2012, 5, 1), new LocalDate(2012, 6, 1), InvoiceItemType.RECURRING, new BigDecimal("249.95")),
+                                    new ExpectedInvoiceItemCheck(new LocalDate(2012, 4, 1), new LocalDate(2012, 5, 1), InvoiceItemType.USAGE, new BigDecimal("5.90")));
+
+
+    }
+
+    private void setUsage(final RolledUpUsage...usages) {
+        final List<RolledUpUsage> usageList = new ArrayList<RolledUpUsage>();
+        for (RolledUpUsage usage : usages) {
+            usageList.add(usage);
+        }
+        ((MockUsageUserApi) usageUserApi).setAllUsageForSubscription(usageList);
+    }
+}
diff --git a/catalog/src/main/java/org/killbill/billing/catalog/DefaultBlock.java b/catalog/src/main/java/org/killbill/billing/catalog/DefaultBlock.java
index a8ac56d..14a73ec 100644
--- a/catalog/src/main/java/org/killbill/billing/catalog/DefaultBlock.java
+++ b/catalog/src/main/java/org/killbill/billing/catalog/DefaultBlock.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2014 The Billing Project, Inc.
+ * Copyright 2014 The Billing Project, LLC
  *
  * Ning 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
diff --git a/catalog/src/main/java/org/killbill/billing/catalog/DefaultTier.java b/catalog/src/main/java/org/killbill/billing/catalog/DefaultTier.java
index 105a629..2d430cb 100644
--- a/catalog/src/main/java/org/killbill/billing/catalog/DefaultTier.java
+++ b/catalog/src/main/java/org/killbill/billing/catalog/DefaultTier.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2014 The Billing Project, Inc.
+ * Copyright 2014 The Billing Project, LLC
  *
  * Ning 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
diff --git a/catalog/src/main/java/org/killbill/billing/catalog/DefaultTieredBlock.java b/catalog/src/main/java/org/killbill/billing/catalog/DefaultTieredBlock.java
index e8ee088..3448c2d 100644
--- a/catalog/src/main/java/org/killbill/billing/catalog/DefaultTieredBlock.java
+++ b/catalog/src/main/java/org/killbill/billing/catalog/DefaultTieredBlock.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2014 The Billing Project, Inc.
+ * Copyright 2014 The Billing Project, LLC
  *
  * Ning 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
diff --git a/catalog/src/main/java/org/killbill/billing/catalog/DefaultUsage.java b/catalog/src/main/java/org/killbill/billing/catalog/DefaultUsage.java
index bc75ed7..9b7c328 100644
--- a/catalog/src/main/java/org/killbill/billing/catalog/DefaultUsage.java
+++ b/catalog/src/main/java/org/killbill/billing/catalog/DefaultUsage.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2014 The Billing Project, Inc.
+ * Copyright 2014 The Billing Project, LLC
  *
  * Ning 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
diff --git a/catalog/src/test/resources/catalogTest.xml b/catalog/src/test/resources/catalogTest.xml
index 262842c..ca07fe2 100644
--- a/catalog/src/test/resources/catalogTest.xml
+++ b/catalog/src/test/resources/catalogTest.xml
@@ -37,12 +37,19 @@
         <currency>GBP</currency>
     </currencies>
 
+    <units>
+        <unit name="bullets"/>
+    </units>
+
     <products>
         <product name="Blowdart">
             <category>BASE</category>
         </product>
         <product name="Pistol">
             <category>BASE</category>
+            <available>
+                <addonProduct>Bullets</addonProduct>
+            </available>
         </product>
         <product name="Shotgun">
             <category>BASE</category>
@@ -50,6 +57,7 @@
                 <addonProduct>Telescopic-Scope</addonProduct>
                 <addonProduct>Laser-Scope</addonProduct>
                 <addonProduct>Holster</addonProduct>
+                <addonProduct>Bullets</addonProduct>
             </available>
         </product>
         <product name="Assault-Rifle">
@@ -59,6 +67,7 @@
             </included>
             <available>
                 <addonProduct>Laser-Scope</addonProduct>
+                <addonProduct>Bullets</addonProduct>
             </available>
         </product>
         <product name="Telescopic-Scope">
@@ -76,6 +85,9 @@
         <product name="Refurbish-Maintenance">
             <category>ADD_ON</category>
         </product>
+        <product name="Bullets">
+            <category>ADD_ON</category>
+        </product>
     </products>
 
     <rules>
@@ -963,6 +975,69 @@
                 </recurring>
             </finalPhase>
         </plan>
+        <plan name="bullets-usage-in-arrear">
+            <product>Bullets</product>
+            <finalPhase type="EVERGREEN">
+                <duration>
+                    <unit>UNLIMITED</unit>
+                </duration>
+                <usages>
+                    <usage name="bullets-usage-in-arrear-usage" billingMode="IN_ARREAR" usageType="CONSUMABLE">
+                        <billingPeriod>MONTHLY</billingPeriod>
+                        <tiers>
+                            <tier>
+                                <blocks>
+                                    <tieredBlock>
+                                        <unit>bullets</unit>
+                                        <size>100</size>
+                                        <prices>
+                                            <price>
+                                                <currency>USD</currency>
+                                                <value>2.95</value>
+                                            </price>
+                                            <price>
+                                                <currency>EUR</currency>
+                                                <value>1.95</value>
+                                            </price>
+                                            <price>
+                                                <currency>GBP</currency>
+                                                <value>0.95</value>
+                                            </price>
+                                        </prices>
+                                        <max>10</max>
+                                    </tieredBlock>
+                                </blocks>
+                            </tier>
+                            <tier>
+                                <blocks>
+                                    <tieredBlock>
+                                        <unit>bullets</unit>
+                                        <size>1000</size>
+                                        <prices>
+                                            <price>
+                                                <currency>USD</currency>
+                                                <value>5.95</value>
+                                            </price>
+                                            <price>
+                                                <currency>EUR</currency>
+                                                <value>4.95</value>
+                                            </price>
+                                            <price>
+                                                <currency>GBP</currency>
+                                                <value>3.95</value>
+                                            </price>
+                                        </prices>
+                                        <max>100</max>
+                                    </tieredBlock>
+                                </blocks>
+                            </tier>
+                        </tiers>
+                    </usage>
+                </usages>
+            </finalPhase>
+            <plansAllowedInBundle>-1</plansAllowedInBundle>
+            <!-- arbitrary number of these (multipack) -->
+        </plan>
     </plans>
     <priceLists>
         <defaultPriceList name="DEFAULT">
@@ -980,6 +1055,7 @@
                 <plan>extra-ammo-monthly</plan>
                 <plan>holster-monthly-regular</plan>
                 <plan>refurbish-maintenance</plan>
+                <plan>bullets-usage-in-arrear</plan>
             </plans>
         </defaultPriceList>
         <childPriceList name="gunclubDiscount">
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/generator/DefaultInvoiceGenerator.java b/invoice/src/main/java/org/killbill/billing/invoice/generator/DefaultInvoiceGenerator.java
index 66af2e6..5e2ebe0 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/generator/DefaultInvoiceGenerator.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/generator/DefaultInvoiceGenerator.java
@@ -119,7 +119,7 @@ public class DefaultInvoiceGenerator implements InvoiceGenerator {
             final List<InvoiceItem> items = Lists.newArrayList();
             final Iterator<BillingEvent> events = eventSet.iterator();
 
-            final List<BillingEvent> curEvents = Lists.newArrayList();
+            List<BillingEvent> curEvents = Lists.newArrayList();
             UUID curSubscriptionId = null;
             while (events.hasNext()) {
                 final BillingEvent event = events.next();
@@ -127,11 +127,15 @@ public class DefaultInvoiceGenerator implements InvoiceGenerator {
                 if (curSubscriptionId != null && !curSubscriptionId.equals(subscriptionId)) {
                     final SubscriptionConsumableInArrear subscriptionConsumableInArrear = new SubscriptionConsumableInArrear(invoiceId, curEvents, usageApi, targetDate, context.toTenantContext(tenantId));
                     items.addAll(subscriptionConsumableInArrear.computeMissingUsageInvoiceItems(extractUsageItemsForSubscription(subscriptionId, existingInvoices)));
-                    curEvents.clear();
+                    curEvents = Lists.newArrayList();
                 }
                 curSubscriptionId = subscriptionId;
                 curEvents.add(event);
             }
+            if (curSubscriptionId != null) {
+                final SubscriptionConsumableInArrear subscriptionConsumableInArrear = new SubscriptionConsumableInArrear(invoiceId, curEvents, usageApi, targetDate, context.toTenantContext(tenantId));
+                items.addAll(subscriptionConsumableInArrear.computeMissingUsageInvoiceItems(extractUsageItemsForSubscription(curSubscriptionId, existingInvoices)));
+            }
             return items;
 
         } catch (CatalogApiException e) {
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/model/UsageInvoiceItem.java b/invoice/src/main/java/org/killbill/billing/invoice/model/UsageInvoiceItem.java
index ab32e4b..d9ca64f 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/model/UsageInvoiceItem.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/model/UsageInvoiceItem.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2014 The Billing Project, Inc.
+ * Copyright 2014 The Billing Project, LLC
  *
  * Ning 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
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 b494b5f..4e016f7 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
@@ -1,5 +1,5 @@
 /*
- * Copyright 2014 The Billing Project, Inc.
+ * Copyright 2014 The Billing Project, LLC
  *
  * Ning 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
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/usage/SubscriptionConsumableInArrear.java b/invoice/src/main/java/org/killbill/billing/invoice/usage/SubscriptionConsumableInArrear.java
index f17993e..6707195 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/usage/SubscriptionConsumableInArrear.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/usage/SubscriptionConsumableInArrear.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2014 The Billing Project, Inc.
+ * Copyright 2014 The Billing Project, LLC
  *
  * Ning 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
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/usage/UsageUtils.java b/invoice/src/main/java/org/killbill/billing/invoice/usage/UsageUtils.java
index f60510e..a96b80e 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/usage/UsageUtils.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/usage/UsageUtils.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2014 The Billing Project, Inc.
+ * Copyright 2014 The Billing Project, LLC
  *
  * Ning 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
@@ -19,6 +19,7 @@ package org.killbill.billing.invoice.usage;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -52,8 +53,9 @@ public class UsageUtils {
         final Iterable<Usage> filteredUsages = (filter != null) ? Iterables.filter(usages, filter) : usages;
 
         final Map<String, Usage> result = (filteredUsages.iterator().hasNext()) ? new HashMap<String, Usage>() : Collections.<String, Usage>emptyMap();
-        while (filteredUsages.iterator().hasNext()) {
-            final Usage next = filteredUsages.iterator().next();
+        final Iterator<Usage> iterator = filteredUsages.iterator();
+        while (iterator.hasNext()) {
+            final Usage next = iterator.next();
             result.put(next.getName(), next);
         }
         return result;
diff --git a/invoice/src/main/resources/org/killbill/billing/invoice/dao/InvoiceItemSqlDao.sql.stg b/invoice/src/main/resources/org/killbill/billing/invoice/dao/InvoiceItemSqlDao.sql.stg
index f5d7eb2..2ce721a 100644
--- a/invoice/src/main/resources/org/killbill/billing/invoice/dao/InvoiceItemSqlDao.sql.stg
+++ b/invoice/src/main/resources/org/killbill/billing/invoice/dao/InvoiceItemSqlDao.sql.stg
@@ -10,6 +10,7 @@ tableFields(prefix) ::= <<
 , <prefix>subscription_id
 , <prefix>plan_name
 , <prefix>phase_name
+, <prefix>usage_name
 , <prefix>start_date
 , <prefix>end_date
 , <prefix>amount
@@ -28,6 +29,7 @@ tableValues() ::= <<
 , :subscriptionId
 , :planName
 , :phaseName
+, :usageName
 , :startDate
 , :endDate
 , :amount
diff --git a/invoice/src/test/java/org/killbill/billing/invoice/usage/TestContiguousIntervalConsumableInArrear.java b/invoice/src/test/java/org/killbill/billing/invoice/usage/TestContiguousIntervalConsumableInArrear.java
index 41b14e3..0e9d662 100644
--- a/invoice/src/test/java/org/killbill/billing/invoice/usage/TestContiguousIntervalConsumableInArrear.java
+++ b/invoice/src/test/java/org/killbill/billing/invoice/usage/TestContiguousIntervalConsumableInArrear.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2014 The Billing Project, Inc.
+ * Copyright 2014 The Billing Project, LLC
  *
  * Ning 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
diff --git a/invoice/src/test/java/org/killbill/billing/invoice/usage/TestSubscriptionConsumableInArrear.java b/invoice/src/test/java/org/killbill/billing/invoice/usage/TestSubscriptionConsumableInArrear.java
index 4512083..06df090 100644
--- a/invoice/src/test/java/org/killbill/billing/invoice/usage/TestSubscriptionConsumableInArrear.java
+++ b/invoice/src/test/java/org/killbill/billing/invoice/usage/TestSubscriptionConsumableInArrear.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2014 The Billing Project, Inc.
+ * Copyright 2014 The Billing Project, LLC
  *
  * Ning 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
diff --git a/invoice/src/test/java/org/killbill/billing/invoice/usage/TestUsageInArrearBase.java b/invoice/src/test/java/org/killbill/billing/invoice/usage/TestUsageInArrearBase.java
index abca9a7..994fac4 100644
--- a/invoice/src/test/java/org/killbill/billing/invoice/usage/TestUsageInArrearBase.java
+++ b/invoice/src/test/java/org/killbill/billing/invoice/usage/TestUsageInArrearBase.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2014 The Billing Project, Inc.
+ * Copyright 2014 The Billing Project, LLC
  *
  * Ning 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
diff --git a/jaxrs/src/test/java/org/killbill/billing/jaxrs/json/TestInvoiceItemJsonSimple.java b/jaxrs/src/test/java/org/killbill/billing/jaxrs/json/TestInvoiceItemJsonSimple.java
index 9e3f7ab..96eb7a7 100644
--- a/jaxrs/src/test/java/org/killbill/billing/jaxrs/json/TestInvoiceItemJsonSimple.java
+++ b/jaxrs/src/test/java/org/killbill/billing/jaxrs/json/TestInvoiceItemJsonSimple.java
@@ -63,6 +63,7 @@ public class TestInvoiceItemJsonSimple extends JaxrsTestSuiteNoDB {
         Assert.assertEquals(invoiceItemJson.getSubscriptionId(), subscriptionId);
         Assert.assertEquals(invoiceItemJson.getPlanName(), planName);
         Assert.assertEquals(invoiceItemJson.getPhaseName(), phaseName);
+        Assert.assertEquals(invoiceItemJson.getUsageName(), usageName);
         Assert.assertEquals(invoiceItemJson.getItemType(), type);
         Assert.assertEquals(invoiceItemJson.getDescription(), description);
         Assert.assertEquals(invoiceItemJson.getStartDate(), startDate);
@@ -87,6 +88,7 @@ public class TestInvoiceItemJsonSimple extends JaxrsTestSuiteNoDB {
         Mockito.when(invoiceItem.getSubscriptionId()).thenReturn(UUID.randomUUID());
         Mockito.when(invoiceItem.getPlanName()).thenReturn(UUID.randomUUID().toString());
         Mockito.when(invoiceItem.getPhaseName()).thenReturn(UUID.randomUUID().toString());
+        Mockito.when(invoiceItem.getUsageName()).thenReturn(UUID.randomUUID().toString());
         Mockito.when(invoiceItem.getDescription()).thenReturn(UUID.randomUUID().toString());
         Mockito.when(invoiceItem.getStartDate()).thenReturn(clock.getUTCToday());
         Mockito.when(invoiceItem.getEndDate()).thenReturn(clock.getUTCToday());
@@ -103,6 +105,7 @@ public class TestInvoiceItemJsonSimple extends JaxrsTestSuiteNoDB {
         Assert.assertEquals(invoiceItemJson.getSubscriptionId(), invoiceItem.getSubscriptionId().toString());
         Assert.assertEquals(invoiceItemJson.getPlanName(), invoiceItem.getPlanName());
         Assert.assertEquals(invoiceItemJson.getPhaseName(), invoiceItem.getPhaseName());
+        Assert.assertEquals(invoiceItemJson.getUsageName(), invoiceItem.getUsageName());
         Assert.assertEquals(invoiceItemJson.getDescription(), invoiceItem.getDescription());
         Assert.assertEquals(invoiceItemJson.getStartDate(), invoiceItem.getStartDate());
         Assert.assertEquals(invoiceItemJson.getEndDate(), invoiceItem.getEndDate());
diff --git a/usage/src/test/java/org/killbill/billing/usage/api/user/MockUsageUserApi.java b/usage/src/test/java/org/killbill/billing/usage/api/user/MockUsageUserApi.java
new file mode 100644
index 0000000..2cac2ff
--- /dev/null
+++ b/usage/src/test/java/org/killbill/billing/usage/api/user/MockUsageUserApi.java
@@ -0,0 +1,37 @@
+package org.killbill.billing.usage.api.user;
+
+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.usage.api.RolledUpUsage;
+import org.killbill.billing.usage.api.UsageUserApi;
+import org.killbill.billing.util.callcontext.CallContext;
+import org.killbill.billing.util.callcontext.TenantContext;
+
+
+public class MockUsageUserApi implements UsageUserApi {
+
+    private List<RolledUpUsage> result;
+
+    @Override
+    public void recordRolledUpUsage(final UUID uuid, final String s, final DateTime dateTime, final DateTime dateTime2, final BigDecimal bigDecimal, final CallContext callContext) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public RolledUpUsage getUsageForSubscription(final UUID uuid, final String s, final DateTime dateTime, final DateTime dateTime2, final TenantContext tenantContext) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public List<RolledUpUsage> getAllUsageForSubscription(final UUID uuid, final Set<String> strings, final List<DateTime> dateTimes, final TenantContext tenantContext) {
+        return result;
+    }
+
+    public void setAllUsageForSubscription(final List<RolledUpUsage> result) {
+        this.result = result;
+    }
+}
diff --git a/usage/src/test/java/org/killbill/billing/usage/glue/TestUsageModule.java b/usage/src/test/java/org/killbill/billing/usage/glue/TestUsageModule.java
index c03237d..8ea3749 100644
--- a/usage/src/test/java/org/killbill/billing/usage/glue/TestUsageModule.java
+++ b/usage/src/test/java/org/killbill/billing/usage/glue/TestUsageModule.java
@@ -16,6 +16,8 @@
 
 package org.killbill.billing.usage.glue;
 
+import org.killbill.billing.usage.api.UsageUserApi;
+import org.killbill.billing.usage.api.user.MockUsageUserApi;
 import org.skife.config.ConfigSource;
 
 public class TestUsageModule extends UsageModule {
@@ -28,4 +30,10 @@ public class TestUsageModule extends UsageModule {
     protected void configure() {
         super.configure();
     }
+
+    protected void installUsageUserApi() {
+        bind(MockUsageUserApi.class).asEagerSingleton();
+        bind(UsageUserApi.class).to(MockUsageUserApi.class).asEagerSingleton();
+    }
+
 }