killbill-memoizeit

analytics: BST changes * Store the account key in BST * Store

11/23/2011 12:14:03 AM

Details

diff --git a/analytics/src/main/java/com/ning/billing/analytics/BusinessSubscription.java b/analytics/src/main/java/com/ning/billing/analytics/BusinessSubscription.java
index 40160ad..691fbe1 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/BusinessSubscription.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/BusinessSubscription.java
@@ -53,7 +53,6 @@ public class BusinessSubscription
     private final String phase;
     private final String billingPeriod;
     private final BigDecimal price;
-    // For convenience, not exposed
     private final String priceList;
     private final BigDecimal mrr;
     private final String currency;
diff --git a/analytics/src/main/java/com/ning/billing/analytics/BusinessSubscriptionTransition.java b/analytics/src/main/java/com/ning/billing/analytics/BusinessSubscriptionTransition.java
index b37e45a..8da7ff0 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/BusinessSubscriptionTransition.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/BusinessSubscriptionTransition.java
@@ -26,16 +26,20 @@ import org.joda.time.DateTime;
 public class BusinessSubscriptionTransition
 {
     private final String key;
+    private final String accountKey;
     private final DateTime requestedTimestamp;
     private final BusinessSubscriptionEvent event;
     private final BusinessSubscription previousSubscription;
     private final BusinessSubscription nextSubscription;
 
-    public BusinessSubscriptionTransition(final String key, final DateTime requestedTimestamp, final BusinessSubscriptionEvent event, final BusinessSubscription previousSubscription, final BusinessSubscription nextsubscription)
+    public BusinessSubscriptionTransition(final String key, final String accountKey, final DateTime requestedTimestamp, final BusinessSubscriptionEvent event, final BusinessSubscription previousSubscription, final BusinessSubscription nextsubscription)
     {
         if (key == null) {
             throw new IllegalArgumentException("An event must have an key");
         }
+        if (accountKey == null) {
+            throw new IllegalArgumentException("An event must have an account key");
+        }
         if (requestedTimestamp == null) {
             throw new IllegalArgumentException("An event must have a requestedTimestamp");
         }
@@ -44,6 +48,7 @@ public class BusinessSubscriptionTransition
         }
 
         this.key = key;
+        this.accountKey = accountKey;
         this.requestedTimestamp = requestedTimestamp;
         this.event = event;
         this.previousSubscription = previousSubscription;
@@ -60,6 +65,11 @@ public class BusinessSubscriptionTransition
         return key;
     }
 
+    public String getAccountKey()
+    {
+        return accountKey;
+    }
+
     public BusinessSubscription getNextSubscription()
     {
         return nextSubscription;
@@ -82,6 +92,7 @@ public class BusinessSubscriptionTransition
         sb.append("BusinessSubscriptionTransition");
         sb.append("{event=").append(event);
         sb.append(", key='").append(key).append('\'');
+        sb.append(", accountKey='").append(accountKey).append('\'');
         sb.append(", requestedTimestamp=").append(requestedTimestamp);
         sb.append(", previousSubscription=").append(previousSubscription);
         sb.append(", nextSubscription=").append(nextSubscription);
@@ -107,6 +118,9 @@ public class BusinessSubscriptionTransition
         if (key != null ? !key.equals(that.key) : that.key != null) {
             return false;
         }
+        if (accountKey != null ? !accountKey.equals(that.accountKey) : that.accountKey != null) {
+            return false;
+        }
         if (nextSubscription != null ? !nextSubscription.equals(that.nextSubscription) : that.nextSubscription != null) {
             return false;
         }
@@ -124,6 +138,7 @@ public class BusinessSubscriptionTransition
     public int hashCode()
     {
         int result = key != null ? key.hashCode() : 0;
+        result = 31 * result + (accountKey != null ? accountKey.hashCode() : 0);
         result = 31 * result + (requestedTimestamp != null ? requestedTimestamp.hashCode() : 0);
         result = 31 * result + (event != null ? event.hashCode() : 0);
         result = 31 * result + (previousSubscription != null ? previousSubscription.hashCode() : 0);
diff --git a/analytics/src/main/java/com/ning/billing/analytics/BusinessSubscriptionTransitionRecorder.java b/analytics/src/main/java/com/ning/billing/analytics/BusinessSubscriptionTransitionRecorder.java
index 37ff0ff..fd57a06 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/BusinessSubscriptionTransitionRecorder.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/BusinessSubscriptionTransitionRecorder.java
@@ -86,6 +86,7 @@ public class BusinessSubscriptionTransitionRecorder
     {
         Currency currency = null;
         String transitionKey = null;
+        String accountKey = null;
 
         // Retrieve key and currency via the bundle
         final ISubscriptionBundle bundle = entitlementApi.getBundleFromId(transition.getBundleId());
@@ -94,6 +95,7 @@ public class BusinessSubscriptionTransitionRecorder
 
             final IAccount account = accountApi.getAccountFromId(bundle.getAccountId());
             if (account != null) {
+                accountKey = account.getKey();
                 currency = account.getCurrency();
             }
         }
@@ -110,17 +112,24 @@ public class BusinessSubscriptionTransitionRecorder
         }
 
         // TODO Support currency changes
-        final BusinessSubscription prevSubscription = new BusinessSubscription(transition.getPreviousPriceList(),transition.getPreviousPlan(), transition.getPreviousPhase(), currency, previousEffectiveTransitionTime, transition.getPreviousState(), transition.getSubscriptionId(), transition.getBundleId());
+        final BusinessSubscription prevSubscription;
+        if (previousEffectiveTransitionTime == null) {
+            prevSubscription = null;
+        }
+        else {
+            prevSubscription = new BusinessSubscription(transition.getPreviousPriceList(), transition.getPreviousPlan(), transition.getPreviousPhase(), currency, previousEffectiveTransitionTime, transition.getPreviousState(), transition.getSubscriptionId(), transition.getBundleId());
+        }
         final BusinessSubscription nextSubscription = new BusinessSubscription(transition.getNextPriceList(), transition.getNextPlan(), transition.getNextPhase(), currency, transition.getEffectiveTransitionTime(), transition.getNextState(), transition.getSubscriptionId(), transition.getBundleId());
 
-        record(transitionKey, transition.getRequestedTransitionTime(), event, prevSubscription, nextSubscription);
+        record(transitionKey, accountKey, transition.getRequestedTransitionTime(), event, prevSubscription, nextSubscription);
     }
 
     // Public for internal reasons
-    public void record(final String key, final DateTime requestedDateTime, final BusinessSubscriptionEvent event, final BusinessSubscription prevSubscription, final BusinessSubscription nextSubscription)
+    public void record(final String key, final String accountKey, final DateTime requestedDateTime, final BusinessSubscriptionEvent event, final BusinessSubscription prevSubscription, final BusinessSubscription nextSubscription)
     {
         final BusinessSubscriptionTransition transition = new BusinessSubscriptionTransition(
             key,
+            accountKey,
             requestedDateTime,
             event,
             prevSubscription,
diff --git a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessSubscriptionTransitionBinder.java b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessSubscriptionTransitionBinder.java
index ccf2a2b..374f296 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessSubscriptionTransitionBinder.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessSubscriptionTransitionBinder.java
@@ -44,6 +44,7 @@ public @interface BusinessSubscriptionTransitionBinder
                 public void bind(final SQLStatement q, final BusinessSubscriptionTransitionBinder bind, final BusinessSubscriptionTransition arg)
                 {
                     q.bind("event_key", arg.getKey());
+                    q.bind("account_key", arg.getAccountKey());
                     q.bind("requested_timestamp", arg.getRequestedTimestamp().getMillis());
                     q.bind("event", arg.getEvent().toString());
 
@@ -56,6 +57,7 @@ public @interface BusinessSubscriptionTransitionBinder
                         q.bindNull("prev_phase", Types.VARCHAR);
                         q.bindNull("prev_billing_period", Types.VARCHAR);
                         q.bindNull("prev_price", Types.NUMERIC);
+                        q.bindNull("prev_price_list", Types.VARCHAR);
                         q.bindNull("prev_mrr", Types.NUMERIC);
                         q.bindNull("prev_currency", Types.VARCHAR);
                         q.bindNull("prev_start_date", Types.BIGINT);
@@ -76,6 +78,7 @@ public @interface BusinessSubscriptionTransitionBinder
                         q.bind("prev_phase", previousSubscription.getPhase());
                         q.bind("prev_billing_period", previousSubscription.getBillingPeriod());
                         q.bind("prev_price", previousSubscription.getRoundedPrice());
+                        q.bind("prev_price_list", previousSubscription.getPriceList());
                         q.bind("prev_mrr", previousSubscription.getRoundedMrr());
                         q.bind("prev_currency", previousSubscription.getCurrency());
                         if (previousSubscription.getStartDate() == null) {
@@ -113,6 +116,7 @@ public @interface BusinessSubscriptionTransitionBinder
                         q.bindNull("next_phase", Types.VARCHAR);
                         q.bindNull("next_billing_period", Types.VARCHAR);
                         q.bindNull("next_price", Types.NUMERIC);
+                        q.bindNull("next_price_list", Types.VARCHAR);
                         q.bindNull("next_mrr", Types.NUMERIC);
                         q.bindNull("next_currency", Types.VARCHAR);
                         q.bindNull("next_start_date", Types.BIGINT);
@@ -133,6 +137,7 @@ public @interface BusinessSubscriptionTransitionBinder
                         q.bind("next_phase", nextSubscription.getPhase());
                         q.bind("next_billing_period", nextSubscription.getBillingPeriod());
                         q.bind("next_price", nextSubscription.getRoundedPrice());
+                        q.bind("next_price_list", nextSubscription.getPriceList());
                         q.bind("next_mrr", nextSubscription.getRoundedMrr());
                         q.bind("next_currency", nextSubscription.getCurrency());
                         if (nextSubscription.getStartDate() == null) {
diff --git a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessSubscriptionTransitionMapper.java b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessSubscriptionTransitionMapper.java
index 015f8bf..fb5e641 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessSubscriptionTransitionMapper.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessSubscriptionTransitionMapper.java
@@ -38,20 +38,20 @@ public class BusinessSubscriptionTransitionMapper implements ResultSetMapper<Bus
     public BusinessSubscriptionTransition map(final int index, final ResultSet r, final StatementContext ctx) throws SQLException
     {
         BusinessSubscription prev = new BusinessSubscription(
-            r.getString(4), // productName
-            r.getString(5), // productType
-            r.getString(6) == null ? null : ProductCategory.valueOf(r.getString(6)), // productCategory
-            r.getString(7), // slug
-            r.getString(8),  // phase
-            r.getString(9),  // billing period
-            BigDecimal.valueOf(r.getDouble(10)), // price
-            null,
-            BigDecimal.valueOf(r.getDouble(11)), // mrr
-            r.getString(12), // currency
-            r.getLong(13) == 0 ? null : new DateTime(r.getLong(13), DateTimeZone.UTC), // startDate
-            r.getString(14) == null ? null : SubscriptionState.valueOf(r.getString(14)), // state
-            r.getString(15) == null ? null : UUID.fromString(r.getString(15)), // subscriptionId
-            r.getString(16) == null ? null : UUID.fromString(r.getString(16)) //bundleId
+            r.getString(5), // productName
+            r.getString(6), // productType
+            r.getString(7) == null ? null : ProductCategory.valueOf(r.getString(7)), // productCategory
+            r.getString(8), // slug
+            r.getString(9),  // phase
+            r.getString(10),  // billing period
+            BigDecimal.valueOf(r.getDouble(11)), // price
+            r.getString(12), // priceList
+            BigDecimal.valueOf(r.getDouble(13)), // mrr
+            r.getString(14), // currency
+            r.getLong(15) == 0 ? null : new DateTime(r.getLong(15), DateTimeZone.UTC), // startDate
+            r.getString(16) == null ? null : SubscriptionState.valueOf(r.getString(16)), // state
+            r.getString(17) == null ? null : UUID.fromString(r.getString(17)), // subscriptionId
+            r.getString(18) == null ? null : UUID.fromString(r.getString(18)) //bundleId
         );
 
         // Avoid creating a dummy subscriptions with all null fields
@@ -60,20 +60,20 @@ public class BusinessSubscriptionTransitionMapper implements ResultSetMapper<Bus
         }
 
         BusinessSubscription next = new BusinessSubscription(
-            r.getString(17), // productName
-            r.getString(18), // productType
-            r.getString(19) == null ? null : ProductCategory.valueOf(r.getString(19)), // productCategory
-            r.getString(20), // slug8
-            r.getString(21),  // phase
-            r.getString(22),  // billing period
-            BigDecimal.valueOf(r.getDouble(23)), // price
-            null,
-            BigDecimal.valueOf(r.getDouble(24)), // mrr
-            r.getString(25), // currency
-            r.getLong(26) == 0 ? null : new DateTime(r.getLong(26), DateTimeZone.UTC), // startDate
-            r.getString(27) == null ? null : SubscriptionState.valueOf(r.getString(27)), // state
-            r.getString(28) == null ? null : UUID.fromString(r.getString(28)), // subscriptionId
-            r.getString(29) == null ? null : UUID.fromString(r.getString(29)) //bundleId
+            r.getString(19), // productName
+            r.getString(20), // productType
+            r.getString(21) == null ? null : ProductCategory.valueOf(r.getString(21)), // productCategory
+            r.getString(22), // slug8
+            r.getString(23),  // phase
+            r.getString(24),  // billing period
+            BigDecimal.valueOf(r.getDouble(25)), // price
+            r.getString(26), // priceList
+            BigDecimal.valueOf(r.getDouble(27)), // mrr
+            r.getString(28), // currency
+            r.getLong(29) == 0 ? null : new DateTime(r.getLong(29), DateTimeZone.UTC), // startDate
+            r.getString(30) == null ? null : SubscriptionState.valueOf(r.getString(30)), // state
+            r.getString(31) == null ? null : UUID.fromString(r.getString(31)), // subscriptionId
+            r.getString(32) == null ? null : UUID.fromString(r.getString(32)) //bundleId
         );
 
         // Avoid creating a dummy subscriptions with all null fields
@@ -81,11 +81,12 @@ public class BusinessSubscriptionTransitionMapper implements ResultSetMapper<Bus
             next = null;
         }
 
-        final BusinessSubscriptionEvent event = BusinessSubscriptionEvent.valueOf(r.getString(3));
+        final BusinessSubscriptionEvent event = BusinessSubscriptionEvent.valueOf(r.getString(4));
 
         return new BusinessSubscriptionTransition(
             r.getString(1),
-            new DateTime(r.getLong(2), DateTimeZone.UTC),
+            r.getString(2),
+            new DateTime(r.getLong(3), DateTimeZone.UTC),
             event,
             prev,
             next
diff --git a/analytics/src/main/resources/com/ning/billing/analytics/dao/BusinessSubscriptionTransitionDao.sql.stg b/analytics/src/main/resources/com/ning/billing/analytics/dao/BusinessSubscriptionTransitionDao.sql.stg
index 11e160a..1654b5b 100644
--- a/analytics/src/main/resources/com/ning/billing/analytics/dao/BusinessSubscriptionTransitionDao.sql.stg
+++ b/analytics/src/main/resources/com/ning/billing/analytics/dao/BusinessSubscriptionTransitionDao.sql.stg
@@ -3,6 +3,7 @@ group BusinessSubscriptionTransition;
 getTransitions(event_key) ::= <<
   select
     event_key
+  , account_key
   , requested_timestamp
   , event
   , prev_product_name
@@ -12,6 +13,7 @@ getTransitions(event_key) ::= <<
   , prev_phase
   , prev_billing_period
   , prev_price
+  , prev_price_list
   , prev_mrr
   , prev_currency
   , prev_start_date
@@ -25,6 +27,7 @@ getTransitions(event_key) ::= <<
   , next_phase
   , next_billing_period
   , next_price
+  , next_price_list
   , next_mrr
   , next_currency
   , next_start_date
@@ -40,6 +43,7 @@ getTransitions(event_key) ::= <<
 createTransition() ::= <<
   insert into bst(
     event_key
+  , account_key
   , requested_timestamp
   , event
   , prev_product_name
@@ -49,6 +53,7 @@ createTransition() ::= <<
   , prev_phase
   , prev_billing_period
   , prev_price
+  , prev_price_list
   , prev_mrr
   , prev_currency
   , prev_start_date
@@ -62,6 +67,7 @@ createTransition() ::= <<
   , next_phase
   , next_billing_period
   , next_price
+  , next_price_list
   , next_mrr
   , next_currency
   , next_start_date
@@ -70,6 +76,7 @@ createTransition() ::= <<
   , next_bundle_id
   ) values (
     :event_key
+  , :account_key
   , :requested_timestamp
   , :event
   , :prev_product_name
@@ -79,6 +86,7 @@ createTransition() ::= <<
   , :prev_phase
   , :prev_billing_period
   , :prev_price
+  , :prev_price_list
   , :prev_mrr
   , :prev_currency
   , :prev_start_date
@@ -92,6 +100,7 @@ createTransition() ::= <<
   , :next_phase
   , :next_billing_period
   , :next_price
+  , :next_price_list
   , :next_mrr
   , :next_currency
   , :next_start_date
diff --git a/analytics/src/main/resources/com/ning/billing/analytics/ddl.sql b/analytics/src/main/resources/com/ning/billing/analytics/ddl.sql
index 908715a..49e48f0 100644
--- a/analytics/src/main/resources/com/ning/billing/analytics/ddl.sql
+++ b/analytics/src/main/resources/com/ning/billing/analytics/ddl.sql
@@ -1,6 +1,7 @@
 drop table if exists bst;
 create table bst (
   event_key varchar(50) not null
+, account_key varchar(50) not null
 , requested_timestamp bigint not null
 , event varchar(50) not null
 , prev_product_name varchar(32) default null
@@ -10,6 +11,7 @@ create table bst (
 , prev_phase varchar(32) default null
 , prev_billing_period varchar(32) default null
 , prev_price numeric(10, 4) default 0
+, prev_price_list varchar(32) default null
 , prev_mrr numeric(10, 4) default 0
 , prev_currency varchar(32) default null
 , prev_start_date bigint default null
@@ -23,6 +25,7 @@ create table bst (
 , next_phase varchar(32) default null
 , next_billing_period varchar(32) default null
 , next_price numeric(10, 4) default 0
+, next_price_list varchar(32) default null
 , next_mrr numeric(10, 4) default 0
 , next_currency varchar(32) default null
 , next_start_date bigint default null
diff --git a/analytics/src/test/java/com/ning/billing/analytics/api/TestAnalyticsService.java b/analytics/src/test/java/com/ning/billing/analytics/api/TestAnalyticsService.java
index e521e33..f4f7c9c 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/api/TestAnalyticsService.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/api/TestAnalyticsService.java
@@ -17,6 +17,8 @@
 package com.ning.billing.analytics.api;
 
 import com.google.inject.Inject;
+import com.ning.billing.account.api.IAccount;
+import com.ning.billing.account.api.IAccountUserApi;
 import com.ning.billing.analytics.AnalyticsTestModule;
 import com.ning.billing.analytics.BusinessSubscription;
 import com.ning.billing.analytics.BusinessSubscriptionEvent;
@@ -27,6 +29,7 @@ import com.ning.billing.analytics.MockPhase;
 import com.ning.billing.analytics.MockPlan;
 import com.ning.billing.analytics.MockProduct;
 import com.ning.billing.analytics.dao.BusinessSubscriptionTransitionDao;
+import com.ning.billing.catalog.api.Currency;
 import com.ning.billing.catalog.api.IPlan;
 import com.ning.billing.catalog.api.IPlanPhase;
 import com.ning.billing.catalog.api.IProduct;
@@ -59,6 +62,10 @@ import java.util.UUID;
 public class TestAnalyticsService
 {
     private static final String KEY = "1234";
+    private static final String ACCOUNT_KEY = "pierre-1234";
+
+    @Inject
+    private IAccountUserApi accountApi;
 
     @Inject
     private IEntitlementUserApi entitlementApi;
@@ -92,7 +99,9 @@ public class TestAnalyticsService
         helper.initDb(entitlementDdl);
 
         // We need a bundle to retrieve the event key
-        final ISubscriptionBundle bundle = entitlementApi.createBundleForAccount(new MockAccount(KEY), KEY);
+        final MockAccount account = new MockAccount(UUID.randomUUID(), ACCOUNT_KEY, Currency.USD);
+        final IAccount storedAccount = accountApi.createAccount(account);
+        final ISubscriptionBundle bundle = entitlementApi.createBundleForAccount(storedAccount, KEY);
 
         // Verify we correctly initialized the account subsystem
         Assert.assertNotNull(bundle);
@@ -105,6 +114,7 @@ public class TestAnalyticsService
         final UUID subscriptionId = UUID.randomUUID();
         final DateTime effectiveTransitionTime = new DateTime(DateTimeZone.UTC);
         final DateTime requestedTransitionTime = new DateTime(DateTimeZone.UTC);
+        final String priceList = "something";
         transition = new SubscriptionTransition(
             subscriptionId,
             bundle.getId(),
@@ -119,14 +129,15 @@ public class TestAnalyticsService
             ISubscription.SubscriptionState.ACTIVE,
             plan,
             phase,
-            "something"
+            priceList
         );
         expectedTransition = new BusinessSubscriptionTransition(
             KEY,
+            ACCOUNT_KEY,
             requestedTransitionTime,
             BusinessSubscriptionEvent.subscriptionCreated(plan),
             null,
-            new BusinessSubscription(null, plan, phase, null, effectiveTransitionTime, ISubscription.SubscriptionState.ACTIVE, subscriptionId, bundle.getId())
+            new BusinessSubscription(priceList, plan, phase, null, effectiveTransitionTime, ISubscription.SubscriptionState.ACTIVE, subscriptionId, bundle.getId())
         );
     }
 
diff --git a/analytics/src/test/java/com/ning/billing/analytics/dao/TestAnalyticsDao.java b/analytics/src/test/java/com/ning/billing/analytics/dao/TestAnalyticsDao.java
index 2156a7e..81c71c5 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/dao/TestAnalyticsDao.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/dao/TestAnalyticsDao.java
@@ -84,7 +84,7 @@ public class TestAnalyticsDao
         final BusinessSubscriptionEvent event = BusinessSubscriptionEvent.subscriptionCancelled(plan);
         final DateTime requestedTimestamp = new DateTime(DateTimeZone.UTC);
 
-        transition = new BusinessSubscriptionTransition(EVENT_KEY, requestedTimestamp, event, prevSubscription, nextSubscription);
+        transition = new BusinessSubscriptionTransition(EVENT_KEY, ACCOUNT_KEY, requestedTimestamp, event, prevSubscription, nextSubscription);
 
         final IDBI dbi = helper.getDBI();
         businessSubscriptionTransitionDao = dbi.onDemand(BusinessSubscriptionTransitionDao.class);
@@ -134,6 +134,7 @@ public class TestAnalyticsDao
     {
         final BusinessSubscriptionTransition transitionWithNullPrev = new BusinessSubscriptionTransition(
             transition.getKey(),
+            transition.getAccountKey(),
             transition.getRequestedTimestamp(),
             transition.getEvent(),
             null,
@@ -151,6 +152,7 @@ public class TestAnalyticsDao
     {
         final BusinessSubscriptionTransition transitionWithNullNext = new BusinessSubscriptionTransition(
             transition.getKey(),
+            transition.getAccountKey(),
             transition.getRequestedTimestamp(),
             transition.getEvent(),
             transition.getPreviousSubscription(),
@@ -169,6 +171,7 @@ public class TestAnalyticsDao
         final BusinessSubscription subscriptionWithNullFields = new BusinessSubscription(null, plan, phase, Currency.USD, null, null, null, null);
         final BusinessSubscriptionTransition transitionWithNullFields = new BusinessSubscriptionTransition(
             transition.getKey(),
+            transition.getAccountKey(),
             transition.getRequestedTimestamp(),
             transition.getEvent(),
             subscriptionWithNullFields,
@@ -187,6 +190,7 @@ public class TestAnalyticsDao
         final BusinessSubscription subscriptionWithNullPlanAndPhase = new BusinessSubscription(null, null, null, Currency.USD, null, null, null, null);
         final BusinessSubscriptionTransition transitionWithNullPlanAndPhase = new BusinessSubscriptionTransition(
             transition.getKey(),
+            transition.getAccountKey(),
             transition.getRequestedTimestamp(),
             transition.getEvent(),
             subscriptionWithNullPlanAndPhase,
@@ -210,6 +214,7 @@ public class TestAnalyticsDao
         final BusinessSubscription subscriptionWithNullPlan = new BusinessSubscription(null, null, phase, Currency.USD, null, null, null, null);
         final BusinessSubscriptionTransition transitionWithNullPlan = new BusinessSubscriptionTransition(
             transition.getKey(),
+            transition.getAccountKey(),
             transition.getRequestedTimestamp(),
             transition.getEvent(),
             subscriptionWithNullPlan,
@@ -229,6 +234,7 @@ public class TestAnalyticsDao
         final BusinessSubscription subscriptionWithNullPhase = new BusinessSubscription(null, plan, null, Currency.USD, null, null, null, null);
         final BusinessSubscriptionTransition transitionWithNullPhase = new BusinessSubscriptionTransition(
             transition.getKey(),
+            transition.getAccountKey(),
             transition.getRequestedTimestamp(),
             transition.getEvent(),
             subscriptionWithNullPhase,
diff --git a/analytics/src/test/java/com/ning/billing/analytics/MockAccount.java b/analytics/src/test/java/com/ning/billing/analytics/MockAccount.java
index c2ab5fd..f22f7b9 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/MockAccount.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/MockAccount.java
@@ -23,73 +23,80 @@ import java.util.UUID;
 
 public class MockAccount implements IAccount
 {
-    private final String key;
+    private final UUID id;
+    private final String accountKey;
+    private final Currency currency;
 
-    public MockAccount(final String key)
+    public MockAccount(final UUID id, final String accountKey, final Currency currency)
     {
-        this.key = key;
+        this.id = id;
+        this.accountKey = accountKey;
+        this.currency = currency;
     }
 
     @Override
     public String getName()
     {
-        return "accountName";
+        throw new UnsupportedOperationException();
     }
 
     @Override
     public String getEmail()
     {
-        return "accountName@yahoo.com";
+        throw new UnsupportedOperationException();
     }
 
     @Override
     public String getPhone()
     {
-        return "4152876341";
+        throw new UnsupportedOperationException();
     }
 
     @Override
     public String getKey()
     {
-        return key;
+        return accountKey;
     }
 
     @Override
     public int getBillCycleDay()
     {
-        return 1;
+        throw new UnsupportedOperationException();
     }
 
     @Override
     public Currency getCurrency()
     {
-        return Currency.USD;
+        return currency;
     }
 
     @Override
     public UUID getId()
     {
-        return UUID.randomUUID();
+        return id;
     }
 
     @Override
     public void load()
     {
+        throw new UnsupportedOperationException();
     }
 
     @Override
     public void save()
     {
+        throw new UnsupportedOperationException();
     }
 
     @Override
     public String getFieldValue(final String fieldName)
     {
-        return null;
+        throw new UnsupportedOperationException();
     }
 
     @Override
     public void setFieldValue(final String fieldName, final String fieldValue)
     {
+        throw new UnsupportedOperationException();
     }
 }
diff --git a/analytics/src/test/java/com/ning/billing/analytics/MockIAccountUserApi.java b/analytics/src/test/java/com/ning/billing/analytics/MockIAccountUserApi.java
index 64fe29f..ccd67af 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/MockIAccountUserApi.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/MockIAccountUserApi.java
@@ -19,12 +19,20 @@ package com.ning.billing.analytics;
 import com.ning.billing.account.api.IAccount;
 import com.ning.billing.account.api.IAccountData;
 import com.ning.billing.account.api.IAccountUserApi;
+import com.ning.billing.catalog.api.Currency;
 
 import java.util.List;
 import java.util.UUID;
 
 public class MockIAccountUserApi implements IAccountUserApi
 {
+    private final MockAccount account;
+
+    public MockIAccountUserApi(final String accountKey, final Currency currency)
+    {
+        account = new MockAccount(UUID.randomUUID(), accountKey, currency);
+    }
+
     @Override
     public IAccount createAccount(final IAccountData data)
     {
@@ -40,7 +48,7 @@ public class MockIAccountUserApi implements IAccountUserApi
     @Override
     public IAccount getAccountFromId(final UUID uid)
     {
-        return null;
+        return account;
     }
 
     @Override
diff --git a/analytics/src/test/java/com/ning/billing/analytics/TestAnalyticsListener.java b/analytics/src/test/java/com/ning/billing/analytics/TestAnalyticsListener.java
index 97b562d..c4612fd 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/TestAnalyticsListener.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/TestAnalyticsListener.java
@@ -16,6 +16,7 @@
 
 package com.ning.billing.analytics;
 
+import com.ning.billing.catalog.api.Currency;
 import com.ning.billing.catalog.api.IPlan;
 import com.ning.billing.catalog.api.IPlanPhase;
 import com.ning.billing.catalog.api.IProduct;
@@ -36,6 +37,8 @@ import java.util.UUID;
 public class TestAnalyticsListener
 {
     private static final String KEY = "1234";
+    private static final String ACCOUNT_KEY = "pierre-1234";
+    private final Currency CURRENCY = Currency.BRL;
 
     private final MockBusinessSubscriptionTransitionDao dao = new MockBusinessSubscriptionTransitionDao();
     private final UUID subscriptionId = UUID.randomUUID();
@@ -50,7 +53,7 @@ public class TestAnalyticsListener
     @BeforeMethod(alwaysRun = true)
     public void setUp() throws Exception
     {
-        final BusinessSubscriptionTransitionRecorder recorder = new BusinessSubscriptionTransitionRecorder(dao, new MockIEntitlementUserApi(bundleUUID, KEY), new MockIAccountUserApi());
+        final BusinessSubscriptionTransitionRecorder recorder = new BusinessSubscriptionTransitionRecorder(dao, new MockIEntitlementUserApi(bundleUUID, KEY), new MockIAccountUserApi(ACCOUNT_KEY, CURRENCY));
         listener = new AnalyticsListener(recorder, null);
     }
 
@@ -97,8 +100,7 @@ public class TestAnalyticsListener
     {
         final BusinessSubscriptionEvent event = BusinessSubscriptionEvent.subscriptionCreated(plan);
         final ISubscription.SubscriptionState subscriptionState = ISubscription.SubscriptionState.ACTIVE;
-        final BusinessSubscription emptyBST = new BusinessSubscription(null, null, null, null, null, null, subscriptionId, bundleUUID);
-        return createExpectedBST(event, requestedTransitionTime, effectiveTransitionTime, emptyBST, subscriptionState);
+        return createExpectedBST(event, requestedTransitionTime, effectiveTransitionTime, null, subscriptionState);
     }
 
     private BusinessSubscriptionTransition createExpectedPausedBST(final DateTime requestedTransitionTime, final DateTime effectiveTransitionTime, final BusinessSubscription lastSubscription)
@@ -132,6 +134,7 @@ public class TestAnalyticsListener
     {
         return new BusinessSubscriptionTransition(
             KEY,
+            ACCOUNT_KEY,
             requestedTransitionTime,
             eventType,
             previousSubscription,
@@ -139,7 +142,7 @@ public class TestAnalyticsListener
                 null,
                 plan,
                 phase,
-                null,
+                CURRENCY,
                 effectiveTransitionTime,
                 nextState,
                 subscriptionId,
diff --git a/analytics/src/test/java/com/ning/billing/analytics/TestBusinessSubscriptionTransition.java b/analytics/src/test/java/com/ning/billing/analytics/TestBusinessSubscriptionTransition.java
index d45a6d4..9cc4c72 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/TestBusinessSubscriptionTransition.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/TestBusinessSubscriptionTransition.java
@@ -28,9 +28,7 @@ import org.testng.Assert;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
-import java.util.Currency;
-
-import static com.ning.billing.catalog.api.Currency.*;
+import static com.ning.billing.catalog.api.Currency.USD;
 
 public class TestBusinessSubscriptionTransition
 {
@@ -39,6 +37,7 @@ public class TestBusinessSubscriptionTransition
     private BusinessSubscriptionEvent event;
     private DateTime requestedTimestamp;
     private String key;
+    private String accountKey;
     private BusinessSubscriptionTransition transition;
 
     @BeforeMethod(alwaysRun = true)
@@ -55,7 +54,8 @@ public class TestBusinessSubscriptionTransition
         event = BusinessSubscriptionEvent.subscriptionCancelled(prevISubscription.getCurrentPlan());
         requestedTimestamp = new DateTime(DateTimeZone.UTC);
         key = "1234";
-        transition = new BusinessSubscriptionTransition(key, requestedTimestamp, event, prevSubscription, nextSubscription);
+        accountKey = "pierre-1234";
+        transition = new BusinessSubscriptionTransition(key, accountKey, requestedTimestamp, event, prevSubscription, nextSubscription);
     }
 
     @Test(groups = "fast")
@@ -76,22 +76,22 @@ public class TestBusinessSubscriptionTransition
 
         BusinessSubscriptionTransition otherTransition;
 
-        otherTransition = new BusinessSubscriptionTransition(key, new DateTime(), event, prevSubscription, nextSubscription);
+        otherTransition = new BusinessSubscriptionTransition(key, accountKey, new DateTime(), event, prevSubscription, nextSubscription);
         Assert.assertTrue(!transition.equals(otherTransition));
 
-        otherTransition = new BusinessSubscriptionTransition("12345", requestedTimestamp, event, prevSubscription, nextSubscription);
+        otherTransition = new BusinessSubscriptionTransition("12345", accountKey, requestedTimestamp, event, prevSubscription, nextSubscription);
         Assert.assertTrue(!transition.equals(otherTransition));
 
-        otherTransition = new BusinessSubscriptionTransition(key, requestedTimestamp, BusinessSubscriptionEvent.subscriptionPaused(null), prevSubscription, nextSubscription);
+        otherTransition = new BusinessSubscriptionTransition(key, accountKey, requestedTimestamp, BusinessSubscriptionEvent.subscriptionPaused(null), prevSubscription, nextSubscription);
         Assert.assertTrue(!transition.equals(otherTransition));
 
-        otherTransition = new BusinessSubscriptionTransition(key, requestedTimestamp, event, prevSubscription, prevSubscription);
+        otherTransition = new BusinessSubscriptionTransition(key, accountKey, requestedTimestamp, event, prevSubscription, prevSubscription);
         Assert.assertTrue(!transition.equals(otherTransition));
 
-        otherTransition = new BusinessSubscriptionTransition(key, requestedTimestamp, event, nextSubscription, nextSubscription);
+        otherTransition = new BusinessSubscriptionTransition(key, accountKey, requestedTimestamp, event, nextSubscription, nextSubscription);
         Assert.assertTrue(!transition.equals(otherTransition));
 
-        otherTransition = new BusinessSubscriptionTransition(key, requestedTimestamp, event, nextSubscription, prevSubscription);
+        otherTransition = new BusinessSubscriptionTransition(key, accountKey, requestedTimestamp, event, nextSubscription, prevSubscription);
         Assert.assertTrue(!transition.equals(otherTransition));
     }
 
@@ -99,7 +99,7 @@ public class TestBusinessSubscriptionTransition
     public void testRejectInvalidTransitions() throws Exception
     {
         try {
-            new BusinessSubscriptionTransition(null, requestedTimestamp, event, prevSubscription, nextSubscription);
+            new BusinessSubscriptionTransition(null, accountKey, requestedTimestamp, event, prevSubscription, nextSubscription);
             Assert.fail();
         }
         catch (IllegalArgumentException e) {
@@ -107,7 +107,7 @@ public class TestBusinessSubscriptionTransition
         }
 
         try {
-            new BusinessSubscriptionTransition(key, null, event, prevSubscription, nextSubscription);
+            new BusinessSubscriptionTransition(key, accountKey, null, event, prevSubscription, nextSubscription);
             Assert.fail();
         }
         catch (IllegalArgumentException e) {
@@ -115,7 +115,7 @@ public class TestBusinessSubscriptionTransition
         }
 
         try {
-            new BusinessSubscriptionTransition(key, requestedTimestamp, null, prevSubscription, nextSubscription);
+            new BusinessSubscriptionTransition(key, accountKey, requestedTimestamp, null, prevSubscription, nextSubscription);
             Assert.fail();
         }
         catch (IllegalArgumentException e) {