Details
diff --git a/analytics/src/main/java/com/ning/billing/analytics/AnalyticsListener.java b/analytics/src/main/java/com/ning/billing/analytics/AnalyticsListener.java
index ba7a707..cce74e7 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/AnalyticsListener.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/AnalyticsListener.java
@@ -18,6 +18,8 @@ package com.ning.billing.analytics;
import com.google.common.eventbus.Subscribe;
import com.google.inject.Inject;
+import com.ning.billing.account.api.AccountChangeNotification;
+import com.ning.billing.account.api.AccountCreationNotification;
import com.ning.billing.entitlement.api.user.SubscriptionTransition;
public class AnalyticsListener
@@ -62,7 +64,18 @@ public class AnalyticsListener
}
@Subscribe
- public void handleAccountChange(final Object event)
+ public void handleAccountCreation(final AccountCreationNotification event)
{
+ bacRecorder.accountCreated(event.getData());
+ }
+
+ @Subscribe
+ public void handleAccountChange(final AccountChangeNotification event)
+ {
+ if (!event.hasChanges()) {
+ return;
+ }
+
+ bacRecorder.accountUpdated(event.getAccountId(), event.getChangedFields());
}
}
diff --git a/analytics/src/main/java/com/ning/billing/analytics/BusinessAccountRecorder.java b/analytics/src/main/java/com/ning/billing/analytics/BusinessAccountRecorder.java
index 185289a..23fbcf4 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/BusinessAccountRecorder.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/BusinessAccountRecorder.java
@@ -18,11 +18,18 @@ package com.ning.billing.analytics;
import com.google.inject.Inject;
import com.ning.billing.account.api.Account;
+import com.ning.billing.account.api.AccountData;
import com.ning.billing.account.api.AccountUserApi;
+import com.ning.billing.account.api.ChangedField;
import com.ning.billing.analytics.dao.BusinessAccountDao;
+import com.ning.billing.util.tag.Tag;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+
public class BusinessAccountRecorder
{
private static final Logger log = LoggerFactory.getLogger(BusinessAccountRecorder.class);
@@ -37,11 +44,35 @@ public class BusinessAccountRecorder
this.accountApi = accountApi;
}
- public void subscriptionCreated(final Account created)
+ public void accountCreated(final AccountData data)
{
+ final Account account = accountApi.getAccountByKey(data.getExternalKey());
+
+ final List<String> tags = new ArrayList<String>();
+ for (final Tag tag : account.getTagList()) {
+ tags.add(tag.getName());
+ }
+
+ // TODO Need payment and invoice api to fill most fields
+ final BusinessAccount bac = new BusinessAccount(
+ account.getExternalKey(),
+ null, // TODO
+ tags,
+ null, // TODO
+ null, // TODO
+ null, // TODO
+ null, // TODO
+ null, // TODO
+ null // TODO
+ );
+
+ log.info("ACCOUNT CREATION " + bac);
+ dao.createAccount(bac);
}
- public void subscriptionUpdated(final Account updated)
+ public void accountUpdated(final UUID accountId, final List<ChangedField> changedFields)
{
+ // None of the fields updated interest us so far - see DefaultAccountChangeNotification
+ // TODO We'll need notifications for tags changes eventually
}
}
diff --git a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessAccountBinder.java b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessAccountBinder.java
index 6a3e218..6478536 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessAccountBinder.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessAccountBinder.java
@@ -30,6 +30,7 @@ import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
+import java.sql.Types;
@BindingAnnotation(BusinessAccountBinder.BacBinderFactory.class)
@Retention(RetentionPolicy.RUNTIME)
@@ -59,7 +60,12 @@ public @interface BusinessAccountBinder
q.bind("account_key", account.getKey());
q.bind("balance", account.getRoundedBalance());
q.bind("tags", joiner.join(account.getTags()));
- q.bind("last_invoice_date", account.getLastInvoiceDate().getMillis());
+ if (account.getLastInvoiceDate() != null) {
+ q.bind("last_invoice_date", account.getLastInvoiceDate().getMillis());
+ }
+ else {
+ q.bindNull("last_invoice_date", Types.BIGINT);
+ }
q.bind("total_invoice_balance", account.getRoundedTotalInvoiceBalance());
q.bind("last_payment_status", account.getLastPaymentStatus());
q.bind("payment_method", account.getPaymentMethod());
diff --git a/analytics/src/test/java/com/ning/billing/analytics/AnalyticsTestModule.java b/analytics/src/test/java/com/ning/billing/analytics/AnalyticsTestModule.java
index 03e102d..3c3de7e 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/AnalyticsTestModule.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/AnalyticsTestModule.java
@@ -22,6 +22,7 @@ import com.ning.billing.catalog.glue.CatalogModule;
import com.ning.billing.dbi.MysqlTestingHelper;
import com.ning.billing.entitlement.glue.EntitlementModule;
import com.ning.billing.util.glue.EventBusModule;
+import com.ning.billing.util.glue.TagStoreModule;
import org.skife.jdbi.v2.DBI;
import org.skife.jdbi.v2.IDBI;
@@ -37,6 +38,7 @@ public class AnalyticsTestModule extends AnalyticsModule
install(new CatalogModule());
install(new EventBusModule());
install(new EntitlementModule());
+ install(new TagStoreModule());
// Install the Dao layer
final MysqlTestingHelper helper = new MysqlTestingHelper();
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 17b6a29..03a27d0 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
@@ -18,15 +18,38 @@ package com.ning.billing.analytics.api;
import com.google.inject.Inject;
import com.ning.billing.account.api.Account;
+import com.ning.billing.account.api.AccountCreationNotification;
import com.ning.billing.account.api.AccountUserApi;
-import com.ning.billing.analytics.*;
+import com.ning.billing.account.api.user.DefaultAccountCreationEvent;
+import com.ning.billing.analytics.AnalyticsTestModule;
+import com.ning.billing.analytics.BusinessSubscription;
+import com.ning.billing.analytics.BusinessSubscriptionEvent;
+import com.ning.billing.analytics.BusinessSubscriptionTransition;
+import com.ning.billing.analytics.MockAccount;
+import com.ning.billing.analytics.MockDuration;
+import com.ning.billing.analytics.MockPhase;
+import com.ning.billing.analytics.MockPlan;
+import com.ning.billing.analytics.MockProduct;
+import com.ning.billing.analytics.dao.BusinessAccountDao;
import com.ning.billing.analytics.dao.BusinessSubscriptionTransitionDao;
-import com.ning.billing.catalog.api.*;
+import com.ning.billing.catalog.api.Currency;
+import com.ning.billing.catalog.api.PhaseType;
+import com.ning.billing.catalog.api.Plan;
+import com.ning.billing.catalog.api.PlanPhase;
+import com.ning.billing.catalog.api.Product;
+import com.ning.billing.catalog.api.ProductCategory;
import com.ning.billing.dbi.MysqlTestingHelper;
-import com.ning.billing.entitlement.api.user.*;
+import com.ning.billing.entitlement.api.user.EntitlementUserApi;
+import com.ning.billing.entitlement.api.user.EntitlementUserApiException;
+import com.ning.billing.entitlement.api.user.Subscription;
+import com.ning.billing.entitlement.api.user.SubscriptionBundle;
+import com.ning.billing.entitlement.api.user.SubscriptionTransition;
+import com.ning.billing.entitlement.api.user.SubscriptionTransitionData;
import com.ning.billing.entitlement.events.EntitlementEvent;
import com.ning.billing.entitlement.events.user.ApiEventType;
import com.ning.billing.util.eventbus.EventBus;
+import com.ning.billing.util.tag.DefaultTagDescription;
+import com.ning.billing.util.tag.dao.TagDescriptionDao;
import org.apache.commons.io.IOUtils;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
@@ -45,6 +68,8 @@ public class TestAnalyticsService
{
private static final String KEY = "1234";
private static final String ACCOUNT_KEY = "pierre-1234";
+ private static final DefaultTagDescription TAG_ONE = new DefaultTagDescription("batch20", "something", false, false, "pierre", new DateTime(DateTimeZone.UTC));
+ private static final DefaultTagDescription TAG_TWO = new DefaultTagDescription("awesome", "something", false, false, "pierre", new DateTime(DateTimeZone.UTC));
@Inject
private AccountUserApi accountApi;
@@ -53,13 +78,19 @@ public class TestAnalyticsService
private EntitlementUserApi entitlementApi;
@Inject
+ private TagDescriptionDao tagDao;
+
+ @Inject
private AnalyticsService service;
@Inject
private EventBus bus;
@Inject
- private BusinessSubscriptionTransitionDao dao;
+ private BusinessSubscriptionTransitionDao subscriptionDao;
+
+ @Inject
+ private BusinessAccountDao accountDao;
@Inject
private MysqlTestingHelper helper;
@@ -67,13 +98,33 @@ public class TestAnalyticsService
private SubscriptionTransition transition;
private BusinessSubscriptionTransition expectedTransition;
+ private AccountCreationNotification accountCreationNotification;
+
@BeforeClass(alwaysRun = true)
public void startMysql() throws IOException, ClassNotFoundException, SQLException, EntitlementUserApiException
{
+ // Killbill generic setup
+ setupBusAndMySQL();
+
+ tagDao.save(TAG_ONE);
+ tagDao.save(TAG_TWO);
+
+ final MockAccount account = new MockAccount(UUID.randomUUID(), ACCOUNT_KEY, Currency.USD);
+ final Account storedAccount = accountApi.createAccount(account);
+ storedAccount.addTag(TAG_ONE, "pierre", new DateTime(DateTimeZone.UTC));
+ storedAccount.addTag(TAG_TWO, "pierre", new DateTime(DateTimeZone.UTC));
+ accountApi.saveAccount(storedAccount);
+
+ // Create events for the bus and expected results
+ createSubscriptionTransitionEvent(storedAccount);
+ createAccountCreationEvent(storedAccount);
+ }
+
+ private void setupBusAndMySQL() throws IOException
+ {
bus.start();
final String analyticsDdl = IOUtils.toString(BusinessSubscriptionTransitionDao.class.getResourceAsStream("/com/ning/billing/analytics/ddl.sql"));
- // For bundles
final String accountDdl = IOUtils.toString(BusinessSubscriptionTransitionDao.class.getResourceAsStream("/com/ning/billing/account/ddl.sql"));
final String entitlementDdl = IOUtils.toString(BusinessSubscriptionTransitionDao.class.getResourceAsStream("/com/ning/billing/entitlement/ddl.sql"));
@@ -81,17 +132,17 @@ public class TestAnalyticsService
helper.initDb(analyticsDdl);
helper.initDb(accountDdl);
helper.initDb(entitlementDdl);
+ }
- // We need a bundle to retrieve the event key
- final MockAccount account = new MockAccount(UUID.randomUUID(), ACCOUNT_KEY, Currency.USD);
- final Account storedAccount = accountApi.createAccount(account);
- final SubscriptionBundle bundle = entitlementApi.createBundleForAccount(storedAccount.getId(), KEY);
+ private void createSubscriptionTransitionEvent(final Account account) throws EntitlementUserApiException
+ {
+ final SubscriptionBundle bundle = entitlementApi.createBundleForAccount(account.getId(), KEY);
// Verify we correctly initialized the account subsystem
Assert.assertNotNull(bundle);
Assert.assertEquals(bundle.getKey(), KEY);
- // Create a subscription transition
+ // Create a subscription transition event
final Product product = new MockProduct("platinum", "subscription", ProductCategory.BASE);
final Plan plan = new MockPlan("platinum-monthly", product);
final PlanPhase phase = new MockPhase(PhaseType.EVERGREEN, plan, MockDuration.UNLIMITED(), 25.95);
@@ -99,6 +150,7 @@ public class TestAnalyticsService
final DateTime effectiveTransitionTime = new DateTime(DateTimeZone.UTC);
final DateTime requestedTransitionTime = new DateTime(DateTimeZone.UTC);
final String priceList = "something";
+
transition = new SubscriptionTransitionData(
UUID.randomUUID(),
subscriptionId,
@@ -126,6 +178,11 @@ public class TestAnalyticsService
);
}
+ private void createAccountCreationEvent(final Account account)
+ {
+ accountCreationNotification = new DefaultAccountCreationEvent(account);
+ }
+
@AfterClass(alwaysRun = true)
public void stopMysql()
{
@@ -146,11 +203,18 @@ public class TestAnalyticsService
Assert.fail("Unable to start the bus or service! " + t);
}
- // Send an event to the bus and make sure our Dao got it
+ // Send events and wait for the async part...
bus.post(transition);
+ bus.post(accountCreationNotification);
Thread.sleep(1000);
- Assert.assertEquals(dao.getTransitions(KEY).size(), 1);
- Assert.assertEquals(dao.getTransitions(KEY).get(0), expectedTransition);
+
+ Assert.assertEquals(subscriptionDao.getTransitions(KEY).size(), 1);
+ Assert.assertEquals(subscriptionDao.getTransitions(KEY).get(0), expectedTransition);
+
+ Assert.assertEquals(accountDao.getAccount(ACCOUNT_KEY).getKey(), ACCOUNT_KEY);
+ Assert.assertEquals(accountDao.getAccount(ACCOUNT_KEY).getTags().size(), 2);
+ Assert.assertTrue(accountDao.getAccount(ACCOUNT_KEY).getTags().indexOf(TAG_ONE.getName()) != -1);
+ Assert.assertTrue(accountDao.getAccount(ACCOUNT_KEY).getTags().indexOf(TAG_TWO.getName()) != -1);
// Test the shutdown sequence
try {
diff --git a/util/src/main/java/com/ning/billing/util/glue/TagDescriptionDaoProvider.java b/util/src/main/java/com/ning/billing/util/glue/TagDescriptionDaoProvider.java
new file mode 100644
index 0000000..31fb306
--- /dev/null
+++ b/util/src/main/java/com/ning/billing/util/glue/TagDescriptionDaoProvider.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2010-2011 Ning, Inc.
+ *
+ * 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 com.ning.billing.util.glue;
+
+import com.google.inject.Inject;
+import com.google.inject.Provider;
+import com.ning.billing.util.tag.dao.TagDescriptionDao;
+import org.skife.jdbi.v2.IDBI;
+
+public class TagDescriptionDaoProvider implements Provider<TagDescriptionDao>
+{
+ private final IDBI dbi;
+
+ @Inject
+ public TagDescriptionDaoProvider(final IDBI dbi)
+ {
+ this.dbi = dbi;
+ }
+
+ @Override
+ public TagDescriptionDao get()
+ {
+ return dbi.onDemand(TagDescriptionDao.class);
+ }
+}
diff --git a/util/src/main/java/com/ning/billing/util/glue/TagStoreDaoProvider.java b/util/src/main/java/com/ning/billing/util/glue/TagStoreDaoProvider.java
new file mode 100644
index 0000000..2c612e6
--- /dev/null
+++ b/util/src/main/java/com/ning/billing/util/glue/TagStoreDaoProvider.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2010-2011 Ning, Inc.
+ *
+ * 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 com.ning.billing.util.glue;
+
+import com.google.inject.Inject;
+import com.google.inject.Provider;
+import com.ning.billing.util.tag.dao.TagStoreDao;
+import org.skife.jdbi.v2.IDBI;
+
+public class TagStoreDaoProvider implements Provider<TagStoreDao>
+{
+ private final IDBI dbi;
+
+ @Inject
+ public TagStoreDaoProvider(final IDBI dbi)
+ {
+ this.dbi = dbi;
+ }
+
+ @Override
+ public TagStoreDao get()
+ {
+ return dbi.onDemand(TagStoreDao.class);
+ }
+}
diff --git a/util/src/main/java/com/ning/billing/util/glue/TagStoreModule.java b/util/src/main/java/com/ning/billing/util/glue/TagStoreModule.java
new file mode 100644
index 0000000..ae14782
--- /dev/null
+++ b/util/src/main/java/com/ning/billing/util/glue/TagStoreModule.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2010-2011 Ning, Inc.
+ *
+ * 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 com.ning.billing.util.glue;
+
+import com.google.inject.AbstractModule;
+import com.ning.billing.util.tag.dao.TagDescriptionDao;
+import com.ning.billing.util.tag.dao.TagStoreDao;
+
+public class TagStoreModule extends AbstractModule
+{
+ @Override
+ protected void configure()
+ {
+ bind(TagDescriptionDao.class).toProvider(TagDescriptionDaoProvider.class).asEagerSingleton();
+ bind(TagStoreDao.class).toProvider(TagStoreDaoProvider.class).asEagerSingleton();
+ }
+}