killbill-memoizeit
Changes
entitlement/pom.xml 15(+1 -14)
entitlement/src/main/java/com/ning/billing/entitlement/api/billing/DefaultEntitlementBillingApi.java 34(+8 -26)
entitlement/src/test/java/com/ning/billing/entitlement/api/billing/BrainDeadAccount.java 202(+0 -202)
entitlement/src/test/java/com/ning/billing/entitlement/api/billing/BrainDeadAccountUserApi.java 83(+0 -83)
entitlement/src/test/java/com/ning/billing/entitlement/api/billing/TestDefaultEntitlementBillingApi.java 46(+13 -33)
invoice/pom.xml 6(+6 -0)
Details
diff --git a/account/src/main/java/com/ning/billing/account/api/DefaultAccount.java b/account/src/main/java/com/ning/billing/account/api/DefaultAccount.java
index 2b916bf..022e341 100644
--- a/account/src/main/java/com/ning/billing/account/api/DefaultAccount.java
+++ b/account/src/main/java/com/ning/billing/account/api/DefaultAccount.java
@@ -104,7 +104,7 @@ public class DefaultAccount extends CustomizableEntityBase implements Account {
}
/**
- * This call is used for testing
+ * This call is used for testing and update from an existing account
* @param id
* @param externalKey
* @param email
@@ -302,6 +302,11 @@ public class DefaultAccount extends CustomizableEntityBase implements Account {
public boolean processPayment() {
return tags.processPayment();
}
+
+ @Override
+ public MutableAccountData toMutableAccountData() {
+ return new MutableAccountData(this);
+ }
@Override
public String toString() {
diff --git a/account/src/main/java/com/ning/billing/account/api/user/DefaultAccountUserApi.java b/account/src/main/java/com/ning/billing/account/api/user/DefaultAccountUserApi.java
index e9f7f49..7e7c33e 100644
--- a/account/src/main/java/com/ning/billing/account/api/user/DefaultAccountUserApi.java
+++ b/account/src/main/java/com/ning/billing/account/api/user/DefaultAccountUserApi.java
@@ -26,6 +26,7 @@ import com.ning.billing.account.api.AccountApiException;
import com.ning.billing.account.api.AccountData;
import com.ning.billing.account.api.DefaultAccount;
import com.ning.billing.account.api.MigrationAccountData;
+import com.ning.billing.account.api.MutableAccountData;
import com.ning.billing.account.dao.AccountDao;
import com.ning.billing.util.clock.Clock;
import com.ning.billing.util.customfield.CustomField;
@@ -43,7 +44,7 @@ public class DefaultAccountUserApi implements com.ning.billing.account.api.Accou
}
@Override
- public Account createAccount(final AccountData data, final List<CustomField> fields, List<Tag> tags) throws AccountApiException {
+ public Account createAccount(final AccountData data, final List<CustomField> fields, final List<Tag> tags) throws AccountApiException {
Account account = new DefaultAccount(data, clock.getUTCNow());
account.addFields(fields);
account.addTags(tags);
@@ -85,14 +86,10 @@ public class DefaultAccountUserApi implements com.ning.billing.account.api.Accou
throw new AccountApiException(e, ErrorCode.ACCOUNT_UPDATE_FAILED);
}
}
-
+
@Override
- public void updateAccount(final String externalKey, final AccountData accountData) throws AccountApiException {
- UUID accountId = getIdFromKey(externalKey);
- if(accountId == null) {
- throw new AccountApiException(ErrorCode.ACCOUNT_DOES_NOT_EXIST_FOR_KEY, externalKey);
- }
-
+ public void updateAccount(final UUID accountId, final AccountData accountData)
+ throws AccountApiException {
Account account = new DefaultAccount(accountId, accountData);
try {
@@ -100,10 +97,20 @@ public class DefaultAccountUserApi implements com.ning.billing.account.api.Accou
} catch (EntityPersistenceException e) {
throw new AccountApiException(e, ErrorCode.ACCOUNT_UPDATE_FAILED);
}
+
}
+ @Override
+ public void updateAccount(final String externalKey, final AccountData accountData) throws AccountApiException {
+ UUID accountId = getIdFromKey(externalKey);
+ if(accountId == null) {
+ throw new AccountApiException(ErrorCode.ACCOUNT_DOES_NOT_EXIST_FOR_KEY, externalKey);
+ }
+ updateAccount(accountId, accountData);
+ }
+
@Override
- public void deleteAccountByKey(String externalKey) throws AccountApiException {
+ public void deleteAccountByKey(final String externalKey) throws AccountApiException {
dao.deleteByKey(externalKey);
}
@@ -124,4 +131,6 @@ public class DefaultAccountUserApi implements com.ning.billing.account.api.Accou
return account;
}
+
+
}
diff --git a/account/src/test/java/com/ning/billing/account/api/MockAccountUserApi.java b/account/src/test/java/com/ning/billing/account/api/MockAccountUserApi.java
index ac74b68..1d49c45 100644
--- a/account/src/test/java/com/ning/billing/account/api/MockAccountUserApi.java
+++ b/account/src/test/java/com/ning/billing/account/api/MockAccountUserApi.java
@@ -132,4 +132,10 @@ public class MockAccountUserApi implements AccountUserApi {
throws AccountApiException {
throw new UnsupportedOperationException();
}
+
+ @Override
+ public void updateAccount(UUID accountId, AccountData accountData)
+ throws AccountApiException {
+ throw new UnsupportedOperationException();
+ }
}
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 d57de25..f25ec05 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/MockAccount.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/MockAccount.java
@@ -24,6 +24,7 @@ import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import com.ning.billing.account.api.Account;
+import com.ning.billing.account.api.MutableAccountData;
import com.ning.billing.catalog.api.Currency;
import com.ning.billing.util.customfield.CustomField;
import com.ning.billing.util.tag.Tag;
@@ -218,4 +219,9 @@ public class MockAccount implements Account
return new DateTime(DateTimeZone.UTC);
}
+ @Override
+ public MutableAccountData toMutableAccountData() {
+ throw new NotImplementedException();
+ }
+
}
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 c6d2369..c410698 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/MockIAccountUserApi.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/MockIAccountUserApi.java
@@ -19,6 +19,8 @@ package com.ning.billing.analytics;
import java.util.List;
import java.util.UUID;
+import org.apache.commons.lang.NotImplementedException;
+
import com.ning.billing.account.api.Account;
import com.ning.billing.account.api.AccountApiException;
import com.ning.billing.account.api.AccountData;
@@ -93,4 +95,10 @@ public class MockIAccountUserApi implements AccountUserApi
throws AccountApiException {
throw new UnsupportedOperationException();
}
+
+ @Override
+ public void updateAccount(UUID accountId, AccountData accountData)
+ throws AccountApiException {
+ throw new NotImplementedException();
+ }
}
diff --git a/api/src/main/java/com/ning/billing/account/api/Account.java b/api/src/main/java/com/ning/billing/account/api/Account.java
index 9f5ad02..ed54ce2 100644
--- a/api/src/main/java/com/ning/billing/account/api/Account.java
+++ b/api/src/main/java/com/ning/billing/account/api/Account.java
@@ -28,4 +28,6 @@ public interface Account extends AccountData, CustomizableEntity, UpdatableEntit
public DateTime getUpdatedDate();
+ public MutableAccountData toMutableAccountData();
+
}
diff --git a/api/src/main/java/com/ning/billing/account/api/AccountUserApi.java b/api/src/main/java/com/ning/billing/account/api/AccountUserApi.java
index 9ee1920..6ac392d 100644
--- a/api/src/main/java/com/ning/billing/account/api/AccountUserApi.java
+++ b/api/src/main/java/com/ning/billing/account/api/AccountUserApi.java
@@ -18,6 +18,10 @@ package com.ning.billing.account.api;
import java.util.List;
import java.util.UUID;
+
+import org.joda.time.DateTimeZone;
+
+import com.ning.billing.catalog.api.Currency;
import com.ning.billing.util.customfield.CustomField;
import com.ning.billing.util.tag.Tag;
@@ -36,7 +40,9 @@ public interface AccountUserApi {
public void updateAccount(Account account) throws AccountApiException;
public void updateAccount(String key, AccountData accountData) throws AccountApiException;
-
+
+ public void updateAccount(UUID accountId, AccountData accountData) throws AccountApiException;
+
public Account getAccountByKey(String key);
public Account getAccountById(UUID accountId);
entitlement/pom.xml 15(+1 -14)
diff --git a/entitlement/pom.xml b/entitlement/pom.xml
index 5347c18..176e14b 100644
--- a/entitlement/pom.xml
+++ b/entitlement/pom.xml
@@ -52,12 +52,7 @@
<artifactId>killbill-catalog</artifactId>
<scope>test</scope>
</dependency>
- <!-- Should be in test scope , but broken right now -->
- <dependency>
- <groupId>com.ning.billing</groupId>
- <artifactId>killbill-account</artifactId>
- </dependency>
- <dependency>
+ <dependency>
<groupId>com.ning.billing</groupId>
<artifactId>killbill-util</artifactId>
<type>test-jar</type>
@@ -82,14 +77,6 @@
<artifactId>management-dbfiles</artifactId>
<scope>test</scope>
</dependency>
- <!-- Same here, this is really debatable whether or not we should keep that here -->
- <dependency>
- <groupId>com.ning.billing</groupId>
- <artifactId>killbill-account</artifactId>
- <type>test-jar</type>
- <scope>test</scope>
- </dependency>
-
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/api/billing/DefaultEntitlementBillingApi.java b/entitlement/src/main/java/com/ning/billing/entitlement/api/billing/DefaultEntitlementBillingApi.java
index 8d78cc7..3029fc2 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/api/billing/DefaultEntitlementBillingApi.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/api/billing/DefaultEntitlementBillingApi.java
@@ -22,7 +22,6 @@ import java.util.SortedSet;
import java.util.TreeSet;
import java.util.UUID;
-import com.ning.billing.catalog.api.Currency;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.skife.jdbi.v2.sqlobject.mixins.Transmogrifier;
@@ -34,11 +33,12 @@ import com.ning.billing.ErrorCode;
import com.ning.billing.account.api.Account;
import com.ning.billing.account.api.AccountApiException;
import com.ning.billing.account.api.AccountUserApi;
-import com.ning.billing.account.api.DefaultAccount;
+import com.ning.billing.account.api.MutableAccountData;
import com.ning.billing.catalog.api.BillingAlignment;
import com.ning.billing.catalog.api.Catalog;
import com.ning.billing.catalog.api.CatalogApiException;
import com.ning.billing.catalog.api.CatalogService;
+import com.ning.billing.catalog.api.Currency;
import com.ning.billing.catalog.api.Plan;
import com.ning.billing.catalog.api.PlanPhase;
import com.ning.billing.catalog.api.PlanPhaseSpecifier;
@@ -153,31 +153,11 @@ public class DefaultEntitlementBillingApi implements EntitlementBillingApi {
} catch (CatalogApiException e) {
log.error("Unexpected catalog error encountered when updating BCD",e);
}
+
+ MutableAccountData modifiedData = account.toMutableAccountData();
+ modifiedData.setBillCycleDay(result);
-
- Account modifiedAccount = new DefaultAccount(
- account.getId(),
- account.getExternalKey(),
- account.getEmail(),
- account.getName(),
- account.getFirstNameLength(),
- account.getCurrency(),
- result,
- account.getPaymentProviderName(),
- account.getTimeZone(),
- account.getLocale(),
- account.getAddress1(),
- account.getAddress2(),
- account.getCompanyName(),
- account.getCity(),
- account.getStateOrProvince(),
- account.getCountry(),
- account.getPostalCode(),
- account.getPhone(),
- account.getCreatedDate(),
- null // Updated date will be set internally
- );
- accountApi.updateAccount(modifiedAccount);
+ accountApi.updateAccount(account.getExternalKey(), modifiedData);
return result;
}
@@ -218,4 +198,6 @@ public class DefaultEntitlementBillingApi implements EntitlementBillingApi {
}
}
}
+
+
}
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/EntitlementDao.java b/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/EntitlementDao.java
index fba1b3d..b6ee805 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/EntitlementDao.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/EntitlementDao.java
@@ -19,18 +19,12 @@ package com.ning.billing.entitlement.engine.dao;
import java.util.List;
import java.util.UUID;
-import org.joda.time.DateTime;
-
-import com.ning.billing.account.api.Account;
-import com.ning.billing.account.dao.AccountSqlDao;
import com.ning.billing.entitlement.api.migration.AccountMigrationData;
import com.ning.billing.entitlement.api.user.Subscription;
import com.ning.billing.entitlement.api.user.SubscriptionBundle;
import com.ning.billing.entitlement.api.user.SubscriptionBundleData;
import com.ning.billing.entitlement.api.user.SubscriptionData;
import com.ning.billing.entitlement.events.EntitlementEvent;
-import com.ning.billing.util.customfield.CustomField;
-import com.ning.billing.util.customfield.dao.FieldStoreDao;
public interface EntitlementDao {
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/EntitlementSqlDao.java b/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/EntitlementSqlDao.java
index cd4267e..e2e9203 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/EntitlementSqlDao.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/EntitlementSqlDao.java
@@ -36,10 +36,7 @@ import com.google.common.base.Predicate;
import com.google.common.collect.Collections2;
import com.google.inject.Inject;
import com.ning.billing.ErrorCode;
-import com.ning.billing.account.api.Account;
-import com.ning.billing.account.dao.AccountSqlDao;
import com.ning.billing.catalog.api.Plan;
-import com.ning.billing.catalog.api.Product;
import com.ning.billing.catalog.api.ProductCategory;
import com.ning.billing.entitlement.api.migration.AccountMigrationData;
import com.ning.billing.entitlement.api.migration.AccountMigrationData.BundleMigrationData;
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/billing/TestDefaultEntitlementBillingApi.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/billing/TestDefaultEntitlementBillingApi.java
index ce84575..080c816 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/billing/TestDefaultEntitlementBillingApi.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/billing/TestDefaultEntitlementBillingApi.java
@@ -151,22 +151,12 @@ public class TestDefaultEntitlementBillingApi {
zeroId, oneId, twoId, EventType.API_USER, ApiEventType.CREATE, then, now, null, null, null, null, SubscriptionState.ACTIVE, nextPlan, nextPhase, nextPriceList, 1, true);
transitions.add(t);
- AccountUserApi accountApi = new BrainDeadAccountUserApi(){
-
- @Override
- public Account getAccountById(UUID accountId) {
- return new BrainDeadAccount(){
- @Override
- public int getBillCycleDay() {
- return 32;
- }
-
- @Override
- public Currency getCurrency() {
- return Currency.USD;
- }
- };
- }} ;
+ AccountUserApi accountApi = BrainDeadProxyFactory.createBrainDeadProxyFor(AccountUserApi.class);
+ Account account = BrainDeadProxyFactory.createBrainDeadProxyFor(Account.class);
+ ((ZombieControl)account).addResult("getBillCycleDay", 32);
+ ((ZombieControl)account).addResult("getCurrency", Currency.USD);
+ ((ZombieControl)accountApi).addResult("getAccountById", account);
+
DefaultEntitlementBillingApi api = new DefaultEntitlementBillingApi(dao,accountApi,catalogService);
SortedSet<BillingEvent> events = api.getBillingEventsForAccount(new UUID(0L,0L));
checkFirstEvent(events, nextPlan, 32, oneId, now, nextPhase, ApiEventType.CREATE.toString());
@@ -207,23 +197,13 @@ public class TestDefaultEntitlementBillingApi {
zeroId, oneId, twoId, EventType.API_USER, ApiEventType.CREATE, then, now, null, null, null, null, SubscriptionState.ACTIVE, nextPlan, nextPhase, nextPriceList, 1, true);
transitions.add(t);
- AccountUserApi accountApi = new BrainDeadAccountUserApi(){
-
- @Override
- public Account getAccountById(UUID accountId) {
- return new BrainDeadAccount(){
- @Override
- public int getBillCycleDay() {
- return 32;
- }
-
- @Override
- public Currency getCurrency() {
- return Currency.USD;
- }
- };
- }} ;
- DefaultEntitlementBillingApi api = new DefaultEntitlementBillingApi(dao,accountApi,catalogService);
+ AccountUserApi accountApi = BrainDeadProxyFactory.createBrainDeadProxyFor(AccountUserApi.class);
+ Account account = BrainDeadProxyFactory.createBrainDeadProxyFor(Account.class);
+ ((ZombieControl)account).addResult("getBillCycleDay", 32);
+ ((ZombieControl)account).addResult("getCurrency", Currency.USD);
+ ((ZombieControl)accountApi).addResult("getAccountById", account);
+
+ DefaultEntitlementBillingApi api = new DefaultEntitlementBillingApi(dao,accountApi,catalogService);
SortedSet<BillingEvent> events = api.getBillingEventsForAccount(new UUID(0L,0L));
checkFirstEvent(events, nextPlan, 32, oneId, now, nextPhase, ApiEventType.CREATE.toString());
}
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/glue/MockEngineModule.java b/entitlement/src/test/java/com/ning/billing/entitlement/glue/MockEngineModule.java
index d46fe83..5c1d6b5 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/glue/MockEngineModule.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/glue/MockEngineModule.java
@@ -16,8 +16,9 @@
package com.ning.billing.entitlement.glue;
-import com.ning.billing.account.glue.AccountModuleWithMocks;
+import com.ning.billing.account.api.AccountUserApi;
import com.ning.billing.catalog.glue.CatalogModule;
+import com.ning.billing.mock.BrainDeadProxyFactory;
import com.ning.billing.util.clock.MockClockModule;
import com.ning.billing.util.glue.BusModule;
@@ -28,7 +29,7 @@ public class MockEngineModule extends EntitlementModule {
super.configure();
install(new BusModule());
install(new CatalogModule());
- install(new AccountModuleWithMocks());
+ bind(AccountUserApi.class).toInstance(BrainDeadProxyFactory.createBrainDeadProxyFor(AccountUserApi.class));
install(new MockClockModule());
}
}
invoice/pom.xml 6(+6 -0)
diff --git a/invoice/pom.xml b/invoice/pom.xml
index 90a72e5..9d68110 100644
--- a/invoice/pom.xml
+++ b/invoice/pom.xml
@@ -54,6 +54,12 @@
<scope>test</scope>
</dependency>
<dependency>
+ <groupId>com.ning.billing</groupId>
+ <artifactId>killbill-account</artifactId>
+ <type>test-jar</type>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<scope>test</scope>
diff --git a/invoice/src/test/java/com/ning/billing/invoice/MockModule.java b/invoice/src/test/java/com/ning/billing/invoice/MockModule.java
index db31602..e93bd7e 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/MockModule.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/MockModule.java
@@ -20,6 +20,7 @@ import org.skife.config.ConfigurationObjectFactory;
import org.skife.jdbi.v2.IDBI;
import com.google.inject.AbstractModule;
+import com.ning.billing.account.api.AccountUserApi;
import com.ning.billing.account.glue.AccountModule;
import com.ning.billing.catalog.glue.CatalogModule;
import com.ning.billing.dbi.DBIProvider;
@@ -27,6 +28,7 @@ import com.ning.billing.dbi.DbiConfig;
import com.ning.billing.dbi.MysqlTestingHelper;
import com.ning.billing.entitlement.glue.EntitlementModule;
import com.ning.billing.invoice.glue.InvoiceModule;
+import com.ning.billing.mock.BrainDeadProxyFactory;
import com.ning.billing.util.clock.Clock;
import com.ning.billing.util.clock.ClockMock;
import com.ning.billing.util.glue.BusModule;
@@ -58,7 +60,9 @@ public class MockModule extends AbstractModule {
install(new GlobalLockerModule());
install(new NotificationQueueModule());
- install(new AccountModule());
+// install(new AccountModule());
+ bind(AccountUserApi.class).toInstance(BrainDeadProxyFactory.createBrainDeadProxyFor(AccountUserApi.class));
+
installEntitlementModule();
install(new CatalogModule());
install(new BusModule());
diff --git a/invoice/src/test/java/com/ning/billing/invoice/TestInvoiceDispatcher.java b/invoice/src/test/java/com/ning/billing/invoice/TestInvoiceDispatcher.java
index e81b916..26983fc 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/TestInvoiceDispatcher.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/TestInvoiceDispatcher.java
@@ -90,18 +90,14 @@ public class TestInvoiceDispatcher {
{
- final String accountDdl = IOUtils.toString(TestInvoiceDispatcher.class.getResourceAsStream("/com/ning/billing/account/ddl.sql"));
final String entitlementDdl = IOUtils.toString(TestInvoiceDispatcher.class.getResourceAsStream("/com/ning/billing/entitlement/ddl.sql"));
final String invoiceDdl = IOUtils.toString(TestInvoiceDispatcher.class.getResourceAsStream("/com/ning/billing/invoice/ddl.sql"));
- // final String paymentDdl = IOUtils.toString(TestInvoiceDispatcher.class.getResourceAsStream("/com/ning/billing/payment/ddl.sql"));
final String utilDdl = IOUtils.toString(TestInvoiceDispatcher.class.getResourceAsStream("/com/ning/billing/util/ddl.sql"));
helper.startMysql();
- helper.initDb(accountDdl);
helper.initDb(entitlementDdl);
helper.initDb(invoiceDdl);
- // helper.initDb(paymentDdl);
helper.initDb(utilDdl);
notifier.initialize();
notifier.start();
diff --git a/util/src/test/java/com/ning/billing/util/notificationq/TestNotificationQueue.java b/util/src/test/java/com/ning/billing/util/notificationq/TestNotificationQueue.java
index 09862e9..1e319d7 100644
--- a/util/src/test/java/com/ning/billing/util/notificationq/TestNotificationQueue.java
+++ b/util/src/test/java/com/ning/billing/util/notificationq/TestNotificationQueue.java
@@ -58,224 +58,226 @@ import com.ning.billing.util.notificationq.dao.NotificationSqlDao;
@Guice(modules = TestNotificationQueue.TestNotificationQueueModule.class)
public class TestNotificationQueue {
- Logger log = LoggerFactory.getLogger(TestNotificationQueue.class);
+ Logger log = LoggerFactory.getLogger(TestNotificationQueue.class);
@Inject
private IDBI dbi;
- @Inject
- MysqlTestingHelper helper;
+ @Inject
+ MysqlTestingHelper helper;
- @Inject
- private Clock clock;
+ @Inject
+ private Clock clock;
- private DummySqlTest dao;
+ private DummySqlTest dao;
- private int eventsReceived;
+ private int eventsReceived;
- // private NotificationQueue queue;
+ // private NotificationQueue queue;
- private void startMysql() throws IOException, ClassNotFoundException, SQLException {
- final String ddl = IOUtils.toString(NotificationSqlDao.class.getResourceAsStream("/com/ning/billing/util/ddl.sql"));
- final String testDdl = IOUtils.toString(NotificationSqlDao.class.getResourceAsStream("/com/ning/billing/util/ddl_test.sql"));
- helper.startMysql();
- helper.initDb(ddl);
- helper.initDb(testDdl);
- }
+ private void startMysql() throws IOException, ClassNotFoundException, SQLException {
+ final String ddl = IOUtils.toString(NotificationSqlDao.class.getResourceAsStream("/com/ning/billing/util/ddl.sql"));
+ final String testDdl = IOUtils.toString(NotificationSqlDao.class.getResourceAsStream("/com/ning/billing/util/ddl_test.sql"));
+ helper.startMysql();
+ helper.initDb(ddl);
+ helper.initDb(testDdl);
+ }
+
+ @BeforeSuite(alwaysRun = true)
+ public void setup() throws Exception {
+ startMysql();
+ dao = dbi.onDemand(DummySqlTest.class);
+ }
- @BeforeSuite(alwaysRun = true)
- public void setup() throws Exception {
- startMysql();
- dao = dbi.onDemand(DummySqlTest.class);
- }
-
@AfterClass(alwaysRun = true)
public void tearDown() {
- helper.stopMysql();
+ helper.stopMysql();
+ }
+
+ @BeforeTest
+ public void beforeTest() {
+ dbi.withHandle(new HandleCallback<Void>() {
+
+ @Override
+ public Void withHandle(Handle handle) throws Exception {
+ handle.execute("delete from notifications");
+ handle.execute("delete from claimed_notifications");
+ handle.execute("delete from dummy");
+ return null;
+ }
+ });
+ // Reset time to real value
+ ((ClockMock) clock).resetDeltaFromReality();
}
- @BeforeTest
- public void beforeTest() {
- dbi.withHandle(new HandleCallback<Void>() {
-
- @Override
- public Void withHandle(Handle handle) throws Exception {
- handle.execute("delete from notifications");
- handle.execute("delete from claimed_notifications");
- handle.execute("delete from dummy");
- return null;
- }
- });
- // Reset time to real value
- ((ClockMock) clock).resetDeltaFromReality();
- }
-
-
-
- /**
- * Test that we can post a notification in the future from a transaction and get the notification
- * callback with the correct key when the time is ready
- * @throws Exception
- */
- @Test(groups={"fast"}, enabled = true)
- public void testSimpleNotification() throws Exception {
-
- final Map<String, Boolean> expectedNotifications = new TreeMap<String, Boolean>();
-
- final DefaultNotificationQueue queue = new DefaultNotificationQueue(dbi, clock, "test-svc", "foo",
- new NotificationQueueHandler() {
- @Override
- public void handleReadyNotification(String notificationKey, DateTime eventDateTime) {
- synchronized (expectedNotifications) {
- log.info("Handler received key: " + notificationKey);
-
- expectedNotifications.put(notificationKey.toString(), Boolean.TRUE);
- expectedNotifications.notify();
- }
- }
- },
- getNotificationConfig(false, 100, 1, 10000));
-
-
- queue.startQueue();
-
- final UUID key = UUID.randomUUID();
- final DummyObject obj = new DummyObject("foo", key);
- final DateTime now = new DateTime();
- final DateTime readyTime = now.plusMillis(2000);
- final NotificationKey notificationKey = new NotificationKey() {
- @Override
- public String toString() {
- return key.toString();
- }
- };
- expectedNotifications.put(notificationKey.toString(), Boolean.FALSE);
-
-
- // Insert dummy to be processed in 2 sec'
- dao.inTransaction(new Transaction<Void, DummySqlTest>() {
- @Override
- public Void inTransaction(DummySqlTest transactional,
- TransactionStatus status) throws Exception {
-
- transactional.insertDummy(obj);
- queue.recordFutureNotificationFromTransaction(transactional,
- readyTime, notificationKey);
- log.info("Posted key: " + notificationKey);
-
- return null;
- }
- });
-
- // Move time in the future after the notification effectiveDate
- ((ClockMock) clock).setDeltaFromReality(3000);
-
- // Notification should have kicked but give it at least a sec' for thread scheduling
- await().atMost(1, MINUTES).until(new Callable<Boolean>() {
+
+
+ /**
+ * Test that we can post a notification in the future from a transaction and get the notification
+ * callback with the correct key when the time is ready
+ * @throws Exception
+ */
+ @Test(groups={"fast"}, enabled = true)
+ public void testSimpleNotification() throws Exception {
+
+ final Map<String, Boolean> expectedNotifications = new TreeMap<String, Boolean>();
+
+ final DefaultNotificationQueue queue = new DefaultNotificationQueue(dbi, clock, "test-svc", "foo",
+ new NotificationQueueHandler() {
+ @Override
+ public void handleReadyNotification(String notificationKey, DateTime eventDateTime) {
+ synchronized (expectedNotifications) {
+ log.info("Handler received key: " + notificationKey);
+
+ expectedNotifications.put(notificationKey.toString(), Boolean.TRUE);
+ expectedNotifications.notify();
+ }
+ }
+ },
+ getNotificationConfig(false, 100, 1, 10000));
+
+
+ queue.startQueue();
+
+ final UUID key = UUID.randomUUID();
+ final DummyObject obj = new DummyObject("foo", key);
+ final DateTime now = new DateTime();
+ final DateTime readyTime = now.plusMillis(2000);
+ final NotificationKey notificationKey = new NotificationKey() {
+ @Override
+ public String toString() {
+ return key.toString();
+ }
+ };
+ expectedNotifications.put(notificationKey.toString(), Boolean.FALSE);
+
+
+ // Insert dummy to be processed in 2 sec'
+ dao.inTransaction(new Transaction<Void, DummySqlTest>() {
+ @Override
+ public Void inTransaction(DummySqlTest transactional,
+ TransactionStatus status) throws Exception {
+
+ transactional.insertDummy(obj);
+ queue.recordFutureNotificationFromTransaction(transactional,
+ readyTime, notificationKey);
+ log.info("Posted key: " + notificationKey);
+
+ return null;
+ }
+ });
+
+ // Move time in the future after the notification effectiveDate
+ ((ClockMock) clock).setDeltaFromReality(3000);
+
+ // Notification should have kicked but give it at least a sec' for thread scheduling
+ await().atMost(1, MINUTES).until(new Callable<Boolean>() {
@Override
public Boolean call() throws Exception {
return expectedNotifications.get(notificationKey.toString());
}
});
- Assert.assertTrue(expectedNotifications.get(notificationKey.toString()));
- }
-
- @Test
- public void testManyNotifications() throws InterruptedException {
- final Map<String, Boolean> expectedNotifications = new TreeMap<String, Boolean>();
-
- final DefaultNotificationQueue queue = new DefaultNotificationQueue(dbi, clock, "test-svc", "many",
- new NotificationQueueHandler() {
- @Override
- public void handleReadyNotification(String notificationKey, DateTime eventDateTime) {
- synchronized (expectedNotifications) {
- expectedNotifications.put(notificationKey, Boolean.TRUE);
- expectedNotifications.notify();
- }
- }
- },
- getNotificationConfig(false, 100, 10, 10000));
-
-
- queue.startQueue();
-
- final DateTime now = clock.getUTCNow();
- final int MAX_NOTIFICATIONS = 100;
- for (int i = 0; i < MAX_NOTIFICATIONS; i++) {
-
- final int nextReadyTimeIncrementMs = 1000;
-
- final UUID key = UUID.randomUUID();
- final DummyObject obj = new DummyObject("foo", key);
- final int currentIteration = i;
-
- final NotificationKey notificationKey = new NotificationKey() {
- @Override
- public String toString() {
- return key.toString();
- }
- };
- expectedNotifications.put(notificationKey.toString(), Boolean.FALSE);
-
- dao.inTransaction(new Transaction<Void, DummySqlTest>() {
- @Override
- public Void inTransaction(DummySqlTest transactional,
- TransactionStatus status) throws Exception {
-
- transactional.insertDummy(obj);
- queue.recordFutureNotificationFromTransaction(transactional,
- now.plus((currentIteration + 1) * nextReadyTimeIncrementMs), notificationKey);
- return null;
- }
- });
-
- // Move time in the future after the notification effectiveDate
- if (i == 0) {
- ((ClockMock) clock).setDeltaFromReality(nextReadyTimeIncrementMs);
- } else {
- ((ClockMock) clock).addDeltaFromReality(nextReadyTimeIncrementMs);
- }
- }
-
- // Wait a little longer since there are a lot of callback that need to happen
- int nbTry = MAX_NOTIFICATIONS + 1;
- boolean success = false;
- do {
- synchronized(expectedNotifications) {
-
- Collection<Boolean> completed = Collections2.filter(expectedNotifications.values(), new Predicate<Boolean>() {
- @Override
- public boolean apply(Boolean input) {
- return input;
- }
- });
-
- if (completed.size() == MAX_NOTIFICATIONS) {
- success = true;
- break;
- }
- //log.debug(String.format("BEFORE WAIT : Got %d notifications at time %s (real time %s)", completed.size(), clock.getUTCNow(), new DateTime()));
- expectedNotifications.wait(1000);
- }
- } while (nbTry-- > 0);
- assertEquals(success, true);
-
- }
-
- /**
- * Test that we can post a notification in the future from a transaction and get the notification
- * callback with the correct key when the time is ready
- * @throws Exception
- */
- @Test(groups={"fast"}, enabled = true)
- public void testMultipleHandlerNotification() throws Exception {
-
- final Map<String, Boolean> expectedNotificationsFred = new TreeMap<String, Boolean>();
- final Map<String, Boolean> expectedNotificationsBarney = new TreeMap<String, Boolean>();
-
- NotificationQueueService notificationQueueService = new DefaultNotificationQueueService(dbi, clock);
-
- NotificationConfig config=new NotificationConfig() {
+ Assert.assertTrue(expectedNotifications.get(notificationKey.toString()));
+ queue.stopQueue();
+ }
+
+ @Test
+ public void testManyNotifications() throws InterruptedException {
+ final Map<String, Boolean> expectedNotifications = new TreeMap<String, Boolean>();
+
+ final DefaultNotificationQueue queue = new DefaultNotificationQueue(dbi, clock, "test-svc", "many",
+ new NotificationQueueHandler() {
+ @Override
+ public void handleReadyNotification(String notificationKey, DateTime eventDateTime) {
+ synchronized (expectedNotifications) {
+ expectedNotifications.put(notificationKey, Boolean.TRUE);
+ expectedNotifications.notify();
+ }
+ }
+ },
+ getNotificationConfig(false, 100, 10, 10000));
+
+
+ queue.startQueue();
+
+ final DateTime now = clock.getUTCNow();
+ final int MAX_NOTIFICATIONS = 100;
+ for (int i = 0; i < MAX_NOTIFICATIONS; i++) {
+
+ final int nextReadyTimeIncrementMs = 1000;
+
+ final UUID key = UUID.randomUUID();
+ final DummyObject obj = new DummyObject("foo", key);
+ final int currentIteration = i;
+
+ final NotificationKey notificationKey = new NotificationKey() {
+ @Override
+ public String toString() {
+ return key.toString();
+ }
+ };
+ expectedNotifications.put(notificationKey.toString(), Boolean.FALSE);
+
+ dao.inTransaction(new Transaction<Void, DummySqlTest>() {
+ @Override
+ public Void inTransaction(DummySqlTest transactional,
+ TransactionStatus status) throws Exception {
+
+ transactional.insertDummy(obj);
+ queue.recordFutureNotificationFromTransaction(transactional,
+ now.plus((currentIteration + 1) * nextReadyTimeIncrementMs), notificationKey);
+ return null;
+ }
+ });
+
+ // Move time in the future after the notification effectiveDate
+ if (i == 0) {
+ ((ClockMock) clock).setDeltaFromReality(nextReadyTimeIncrementMs);
+ } else {
+ ((ClockMock) clock).addDeltaFromReality(nextReadyTimeIncrementMs);
+ }
+ }
+
+ // Wait a little longer since there are a lot of callback that need to happen
+ int nbTry = MAX_NOTIFICATIONS + 1;
+ boolean success = false;
+ do {
+ synchronized(expectedNotifications) {
+
+ Collection<Boolean> completed = Collections2.filter(expectedNotifications.values(), new Predicate<Boolean>() {
+ @Override
+ public boolean apply(Boolean input) {
+ return input;
+ }
+ });
+
+ if (completed.size() == MAX_NOTIFICATIONS) {
+ success = true;
+ break;
+ }
+ //log.debug(String.format("BEFORE WAIT : Got %d notifications at time %s (real time %s)", completed.size(), clock.getUTCNow(), new DateTime()));
+ expectedNotifications.wait(1000);
+ }
+ } while (nbTry-- > 0);
+ assertEquals(success, true);
+ queue.stopQueue();
+
+ }
+
+ /**
+ * Test that we can post a notification in the future from a transaction and get the notification
+ * callback with the correct key when the time is ready
+ * @throws Exception
+ */
+ @Test(groups={"fast"}, enabled = true)
+ public void testMultipleHandlerNotification() throws Exception {
+
+ final Map<String, Boolean> expectedNotificationsFred = new TreeMap<String, Boolean>();
+ final Map<String, Boolean> expectedNotificationsBarney = new TreeMap<String, Boolean>();
+
+ NotificationQueueService notificationQueueService = new DefaultNotificationQueueService(dbi, clock);
+
+ NotificationConfig config=new NotificationConfig() {
@Override
public boolean isNotificationProcessingOff() {
return false;
@@ -292,138 +294,138 @@ public class TestNotificationQueue {
public long getDaoClaimTimeMs() {
return 60000;
}
- };
+ };
- final NotificationQueue queueFred = notificationQueueService.createNotificationQueue("UtilTest", "Fred", new NotificationQueueHandler() {
- @Override
- public void handleReadyNotification(String notificationKey, DateTime eventDateTime) {
- log.info("Fred received key: " + notificationKey);
- expectedNotificationsFred.put(notificationKey, Boolean.TRUE);
- eventsReceived++;
- }
- },
- config);
+ final NotificationQueue queueFred = notificationQueueService.createNotificationQueue("UtilTest", "Fred", new NotificationQueueHandler() {
+ @Override
+ public void handleReadyNotification(String notificationKey, DateTime eventDateTime) {
+ log.info("Fred received key: " + notificationKey);
+ expectedNotificationsFred.put(notificationKey, Boolean.TRUE);
+ eventsReceived++;
+ }
+ },
+ config);
- final NotificationQueue queueBarney = notificationQueueService.createNotificationQueue("UtilTest", "Barney", new NotificationQueueHandler() {
+ final NotificationQueue queueBarney = notificationQueueService.createNotificationQueue("UtilTest", "Barney", new NotificationQueueHandler() {
@Override
public void handleReadyNotification(String notificationKey, DateTime eventDateTime) {
- log.info("Barney received key: " + notificationKey);
- expectedNotificationsBarney.put(notificationKey, Boolean.TRUE);
- eventsReceived++;
+ log.info("Barney received key: " + notificationKey);
+ expectedNotificationsBarney.put(notificationKey, Boolean.TRUE);
+ eventsReceived++;
}
},
config);
- queueFred.startQueue();
-// We don't start Barney so it can never pick up notifications
-
-
- final UUID key = UUID.randomUUID();
- final DummyObject obj = new DummyObject("foo", key);
- final DateTime now = new DateTime();
- final DateTime readyTime = now.plusMillis(2000);
- final NotificationKey notificationKeyFred = new NotificationKey() {
- @Override
- public String toString() {
- return "Fred" ;
- }
- };
-
-
- final NotificationKey notificationKeyBarney = new NotificationKey() {
- @Override
- public String toString() {
- return "Barney" ;
- }
- };
-
- expectedNotificationsFred.put(notificationKeyFred.toString(), Boolean.FALSE);
- expectedNotificationsFred.put(notificationKeyBarney.toString(), Boolean.FALSE);
-
-
- // Insert dummy to be processed in 2 sec'
- dao.inTransaction(new Transaction<Void, DummySqlTest>() {
- @Override
- public Void inTransaction(DummySqlTest transactional,
- TransactionStatus status) throws Exception {
-
- transactional.insertDummy(obj);
- queueFred.recordFutureNotificationFromTransaction(transactional,
- readyTime, notificationKeyFred);
- log.info("posted key: " + notificationKeyFred.toString());
- queueBarney.recordFutureNotificationFromTransaction(transactional,
- readyTime, notificationKeyBarney);
- log.info("posted key: " + notificationKeyBarney.toString());
-
- return null;
- }
- });
-
- // Move time in the future after the notification effectiveDate
- ((ClockMock) clock).setDeltaFromReality(3000);
-
- // Note the timeout is short on this test, but expected behaviour is that it times out.
- // We are checking that the Fred queue does not pick up the Barney event
- try {
- await().atMost(5, TimeUnit.SECONDS).until(new Callable<Boolean>() {
- @Override
- public Boolean call() throws Exception {
- return eventsReceived >= 2;
- }
- });
- Assert.fail("There should only have been one event for the queue to pick up - it got more than that");
- } catch (Exception e) {
- // expected behavior
- }
-
- Assert.assertTrue(expectedNotificationsFred.get(notificationKeyFred.toString()));
- Assert.assertFalse(expectedNotificationsFred.get(notificationKeyBarney.toString()));
- queueFred.stopQueue();
- }
-
- NotificationConfig getNotificationConfig(final boolean off,
- final long sleepTime, final int maxReadyEvents, final long claimTimeMs) {
- return new NotificationConfig() {
- @Override
- public boolean isNotificationProcessingOff() {
- return off;
- }
- @Override
- public long getNotificationSleepTimeMs() {
- return sleepTime;
- }
- @Override
- public int getDaoMaxReadyEvents() {
- return maxReadyEvents;
- }
- @Override
- public long getDaoClaimTimeMs() {
- return claimTimeMs;
- }
- };
- }
-
-
- public static class TestNotificationQueueModule extends AbstractModule {
- @Override
- protected void configure() {
-
- bind(Clock.class).to(ClockMock.class);
-
- final MysqlTestingHelper helper = new MysqlTestingHelper();
- bind(MysqlTestingHelper.class).toInstance(helper);
- IDBI dbi = helper.getDBI();
- bind(IDBI.class).toInstance(dbi);
- IDBI otherDbi = helper.getDBI();
- bind(IDBI.class).annotatedWith(Names.named("global-lock")).toInstance(otherDbi);
- /*
+ queueFred.startQueue();
+ // We don't start Barney so it can never pick up notifications
+
+
+ final UUID key = UUID.randomUUID();
+ final DummyObject obj = new DummyObject("foo", key);
+ final DateTime now = new DateTime();
+ final DateTime readyTime = now.plusMillis(2000);
+ final NotificationKey notificationKeyFred = new NotificationKey() {
+ @Override
+ public String toString() {
+ return "Fred" ;
+ }
+ };
+
+
+ final NotificationKey notificationKeyBarney = new NotificationKey() {
+ @Override
+ public String toString() {
+ return "Barney" ;
+ }
+ };
+
+ expectedNotificationsFred.put(notificationKeyFred.toString(), Boolean.FALSE);
+ expectedNotificationsFred.put(notificationKeyBarney.toString(), Boolean.FALSE);
+
+
+ // Insert dummy to be processed in 2 sec'
+ dao.inTransaction(new Transaction<Void, DummySqlTest>() {
+ @Override
+ public Void inTransaction(DummySqlTest transactional,
+ TransactionStatus status) throws Exception {
+
+ transactional.insertDummy(obj);
+ queueFred.recordFutureNotificationFromTransaction(transactional,
+ readyTime, notificationKeyFred);
+ log.info("posted key: " + notificationKeyFred.toString());
+ queueBarney.recordFutureNotificationFromTransaction(transactional,
+ readyTime, notificationKeyBarney);
+ log.info("posted key: " + notificationKeyBarney.toString());
+
+ return null;
+ }
+ });
+
+ // Move time in the future after the notification effectiveDate
+ ((ClockMock) clock).setDeltaFromReality(3000);
+
+ // Note the timeout is short on this test, but expected behaviour is that it times out.
+ // We are checking that the Fred queue does not pick up the Barney event
+ try {
+ await().atMost(5, TimeUnit.SECONDS).until(new Callable<Boolean>() {
+ @Override
+ public Boolean call() throws Exception {
+ return eventsReceived >= 2;
+ }
+ });
+ Assert.fail("There should only have been one event for the queue to pick up - it got more than that");
+ } catch (Exception e) {
+ // expected behavior
+ }
+
+ Assert.assertTrue(expectedNotificationsFred.get(notificationKeyFred.toString()));
+ Assert.assertFalse(expectedNotificationsFred.get(notificationKeyBarney.toString()));
+ queueFred.stopQueue();
+ }
+
+ NotificationConfig getNotificationConfig(final boolean off,
+ final long sleepTime, final int maxReadyEvents, final long claimTimeMs) {
+ return new NotificationConfig() {
+ @Override
+ public boolean isNotificationProcessingOff() {
+ return off;
+ }
+ @Override
+ public long getNotificationSleepTimeMs() {
+ return sleepTime;
+ }
+ @Override
+ public int getDaoMaxReadyEvents() {
+ return maxReadyEvents;
+ }
+ @Override
+ public long getDaoClaimTimeMs() {
+ return claimTimeMs;
+ }
+ };
+ }
+
+
+ public static class TestNotificationQueueModule extends AbstractModule {
+ @Override
+ protected void configure() {
+
+ bind(Clock.class).to(ClockMock.class);
+
+ final MysqlTestingHelper helper = new MysqlTestingHelper();
+ bind(MysqlTestingHelper.class).toInstance(helper);
+ IDBI dbi = helper.getDBI();
+ bind(IDBI.class).toInstance(dbi);
+ IDBI otherDbi = helper.getDBI();
+ bind(IDBI.class).annotatedWith(Names.named("global-lock")).toInstance(otherDbi);
+ /*
bind(DBI.class).toProvider(DBIProvider.class).asEagerSingleton();
final DbiConfig config = new ConfigurationObjectFactory(System.getProperties()).build(DbiConfig.class);
bind(DbiConfig.class).toInstance(config);
- */
- }
- }
+ */
+ }
+ }
}