killbill-aplcache
Changes
entitlement/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionApiService.java 4(+4 -0)
entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/EntitlementSqlDao.java 76(+64 -12)
entitlement/src/test/java/com/ning/billing/entitlement/api/billing/BrainDeadMockEntitlementDao.java 147(+0 -147)
entitlement/src/test/java/com/ning/billing/entitlement/api/billing/BrainDeadSubscription.java 148(+0 -148)
entitlement/src/test/java/com/ning/billing/entitlement/api/billing/TestDefaultBillingEvent.java 54(+27 -27)
entitlement/src/test/java/com/ning/billing/entitlement/api/billing/TestDefaultEntitlementBillingApi.java 49(+8 -41)
entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserCustomFieldsSql.java 174(+174 -0)
entitlement/src/test/java/com/ning/billing/entitlement/engine/dao/MockEntitlementDaoMemory.java 7(+7 -0)
Details
diff --git a/analytics/src/test/java/com/ning/billing/analytics/MockSubscription.java b/analytics/src/test/java/com/ning/billing/analytics/MockSubscription.java
index f476a59..69abfb4 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/MockSubscription.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/MockSubscription.java
@@ -24,6 +24,8 @@ import com.ning.billing.catalog.api.ProductCategory;
import com.ning.billing.entitlement.api.user.EntitlementUserApiException;
import com.ning.billing.entitlement.api.user.Subscription;
import com.ning.billing.entitlement.api.user.SubscriptionTransition;
+import com.ning.billing.util.customfield.CustomField;
+
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
@@ -154,4 +156,34 @@ public class MockSubscription implements Subscription
throws EntitlementUserApiException {
throw new UnsupportedOperationException();
}
+
+ @Override
+ public String getFieldValue(String fieldName) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void setFieldValue(String fieldName, String fieldValue) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public List<CustomField> getFieldList() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void addFields(List<CustomField> fields) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void clearFields() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public String getObjectName() {
+ throw new UnsupportedOperationException();
+ }
}
diff --git a/api/src/main/java/com/ning/billing/entitlement/api/user/Subscription.java b/api/src/main/java/com/ning/billing/entitlement/api/user/Subscription.java
index eafe210..a9ce2c7 100644
--- a/api/src/main/java/com/ning/billing/entitlement/api/user/Subscription.java
+++ b/api/src/main/java/com/ning/billing/entitlement/api/user/Subscription.java
@@ -21,6 +21,7 @@ import com.ning.billing.catalog.api.Plan;
import com.ning.billing.catalog.api.PlanPhase;
import com.ning.billing.catalog.api.PlanPhaseSpecifier;
import com.ning.billing.catalog.api.ProductCategory;
+import com.ning.billing.util.customfield.CustomizableEntity;
import org.joda.time.DateTime;
@@ -28,7 +29,7 @@ import java.util.List;
import java.util.UUID;
-public interface Subscription {
+public interface Subscription extends CustomizableEntity {
public void cancel(DateTime requestedDate, boolean eot)
throws EntitlementUserApiException;
@@ -47,8 +48,6 @@ public interface Subscription {
CANCELLED
}
- public UUID getId();
-
public UUID getBundleId();
public SubscriptionState getState();
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionApiService.java b/entitlement/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionApiService.java
index eb1f26d..72cc142 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionApiService.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionApiService.java
@@ -278,6 +278,10 @@ public class SubscriptionApiService {
}
}
+ public void commitCustomFields(SubscriptionData subscription) {
+ dao.saveCustomFields(subscription);
+ }
+
private void validateRequestedDate(SubscriptionData subscription, DateTime now, DateTime requestedDate)
throws EntitlementUserApiException {
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionData.java b/entitlement/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionData.java
index 178c4d5..2efe1c5 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionData.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionData.java
@@ -32,6 +32,9 @@ import com.ning.billing.entitlement.events.user.ApiEvent;
import com.ning.billing.entitlement.events.user.ApiEventType;
import com.ning.billing.entitlement.exceptions.EntitlementError;
import com.ning.billing.util.clock.Clock;
+import com.ning.billing.util.customfield.CustomField;
+import com.ning.billing.util.customfield.CustomizableEntityBase;
+
import org.joda.time.DateTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -43,7 +46,7 @@ import java.util.LinkedList;
import java.util.List;
import java.util.UUID;
-public class SubscriptionData implements Subscription {
+public class SubscriptionData extends CustomizableEntityBase implements Subscription {
private final static Logger log = LoggerFactory.getLogger(SubscriptionData.class);
@@ -52,7 +55,6 @@ public class SubscriptionData implements Subscription {
//
// Final subscription fields
//
- private final UUID id;
private final UUID bundleId;
private final DateTime startDate;
private final DateTime bundleStartDate;
@@ -78,10 +80,9 @@ public class SubscriptionData implements Subscription {
}
public SubscriptionData(SubscriptionBuilder builder, SubscriptionApiService apiService, Clock clock) {
- super();
+ super(builder.getId());
this.apiService = apiService;
this.clock = clock;
- this.id = builder.getId();
this.bundleId = builder.getBundleId();
this.startDate = builder.getStartDate();
this.bundleStartDate = builder.getBundleStartDate();
@@ -92,8 +93,27 @@ public class SubscriptionData implements Subscription {
}
@Override
- public UUID getId() {
- return id;
+ public String getObjectName() {
+ return "Subscription";
+ }
+
+
+ @Override
+ public void setFieldValue(String fieldName, String fieldValue) {
+ super.setFieldValue(fieldName, fieldValue);
+ apiService.commitCustomFields(this);
+ }
+
+ @Override
+ public void addFields(List<CustomField> fields) {
+ super.addFields(fields);
+ apiService.commitCustomFields(this);
+ }
+
+ @Override
+ public void clearFields() {
+ super.clearFields();
+ apiService.commitCustomFields(this);
}
@Override
@@ -444,4 +464,5 @@ public class SubscriptionData implements Subscription {
previousPriceList = nextPriceList;
}
}
+
}
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 d7d6b94..fba1b3d 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
@@ -21,12 +21,16 @@ 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 {
@@ -79,4 +83,7 @@ public interface EntitlementDao {
public void undoMigration(UUID accountId);
- }
+ // Custom Fields
+ public void saveCustomFields(SubscriptionData subscription);
+}
+
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 15654d8..e34d48c 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,6 +36,8 @@ 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;
@@ -59,6 +61,8 @@ import com.ning.billing.entitlement.events.user.ApiEventChange;
import com.ning.billing.entitlement.events.user.ApiEventType;
import com.ning.billing.entitlement.exceptions.EntitlementError;
import com.ning.billing.util.clock.Clock;
+import com.ning.billing.util.customfield.CustomField;
+import com.ning.billing.util.customfield.dao.FieldStoreDao;
import com.ning.billing.util.notificationq.NotificationKey;
import com.ning.billing.util.notificationq.NotificationQueue;
import com.ning.billing.util.notificationq.NotificationQueueService;
@@ -166,12 +170,25 @@ public class EntitlementSqlDao implements EntitlementDao {
}
@Override
- public void updateSubscription(SubscriptionData subscription) {
- Date ctd = (subscription.getChargedThroughDate() != null) ? subscription.getChargedThroughDate().toDate() : null;
- Date ptd = (subscription.getPaidThroughDate() != null) ? subscription.getPaidThroughDate().toDate() : null;
- subscriptionsDao.updateSubscription(subscription.getId().toString(), subscription.getActiveVersion(), ctd, ptd);
+ public void updateSubscription(final SubscriptionData subscription) {
+
+ final Date ctd = (subscription.getChargedThroughDate() != null) ? subscription.getChargedThroughDate().toDate() : null;
+ final Date ptd = (subscription.getPaidThroughDate() != null) ? subscription.getPaidThroughDate().toDate() : null;
+
+
+ subscriptionsDao.inTransaction(new Transaction<Void, SubscriptionSqlDao>() {
+
+ @Override
+ public Void inTransaction(SubscriptionSqlDao transactionalDao,
+ TransactionStatus status) throws Exception {
+ transactionalDao.updateSubscription(subscription.getId().toString(), subscription.getActiveVersion(), ctd, ptd);
+ return null;
+ }
+ });
}
+
+
@Override
public void createNextPhaseEvent(final UUID subscriptionId, final EntitlementEvent nextPhase) {
eventsDao.inTransaction(new Transaction<Void, EventSqlDao>() {
@@ -391,17 +408,20 @@ public class EntitlementSqlDao implements EntitlementDao {
}
}
- public Subscription getBaseSubscription(final UUID bundleId, boolean rebuildSubscription) {
- List<Subscription> subscriptions = subscriptionsDao.getSubscriptionsFromBundleId(bundleId.toString());
- for (Subscription cur : subscriptions) {
- if (((SubscriptionData)cur).getCategory() == ProductCategory.BASE) {
- return rebuildSubscription ? buildSubscription(cur) : cur;
- }
+ private void updateCustomFieldsFromTransaction(SubscriptionSqlDao transactionalDao, final SubscriptionData subscription) {
+
+ String SubscriptionId = subscription.getId().toString();
+ String objectType = subscription.getObjectName();
+
+ FieldStoreDao fieldStoreDao = transactionalDao.become(FieldStoreDao.class);
+ fieldStoreDao.clear(SubscriptionId, objectType);
+
+ List<CustomField> fieldList = subscription.getFieldList();
+ if (fieldList != null) {
+ fieldStoreDao.batchSaveFromTransaction(SubscriptionId, objectType, fieldList);
}
- return null;
}
-
private Subscription buildSubscription(Subscription input) {
if (input == null) {
return null;
@@ -491,6 +511,7 @@ public class EntitlementSqlDao implements EntitlementDao {
default:
break;
}
+ loadCustomFields(reloaded);
result.add(reloaded);
}
return result;
@@ -536,6 +557,16 @@ public class EntitlementSqlDao implements EntitlementDao {
}
+ public Subscription getBaseSubscription(final UUID bundleId, boolean rebuildSubscription) {
+ List<Subscription> subscriptions = subscriptionsDao.getSubscriptionsFromBundleId(bundleId.toString());
+ for (Subscription cur : subscriptions) {
+ if (((SubscriptionData)cur).getCategory() == ProductCategory.BASE) {
+ return rebuildSubscription ? buildSubscription(cur) : cur;
+ }
+ }
+ return null;
+ }
+
@Override
public void undoMigration(final UUID accountId) {
@@ -575,4 +606,25 @@ public class EntitlementSqlDao implements EntitlementDao {
}
}
+ @Override
+ public void saveCustomFields(final SubscriptionData subscription) {
+ subscriptionsDao.inTransaction(new Transaction<Void, SubscriptionSqlDao>() {
+ @Override
+ public Void inTransaction(SubscriptionSqlDao transactionalDao,
+ TransactionStatus status) throws Exception {
+ updateCustomFieldsFromTransaction(transactionalDao, subscription);
+ return null;
+ }
+ });
+ }
+
+
+ private void loadCustomFields(final Subscription subscription) {
+ FieldStoreDao fieldStoreDao = subscriptionsDao.become(FieldStoreDao.class);
+ List<CustomField> fields = fieldStoreDao.load(subscription.getId().toString(), subscription.getObjectName());
+ subscription.clearFields();
+ if (fields != null) {
+ subscription.addFields(fields);
+ }
+ }
}
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/billing/TestDefaultBillingEvent.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/billing/TestDefaultBillingEvent.java
index 100d184..fc3362a 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/billing/TestDefaultBillingEvent.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/billing/TestDefaultBillingEvent.java
@@ -40,6 +40,8 @@ import com.ning.billing.catalog.api.Plan;
import com.ning.billing.catalog.api.PlanPhase;
import com.ning.billing.entitlement.api.user.Subscription;
import com.ning.billing.entitlement.api.user.SubscriptionTransition.SubscriptionTransitionType;
+import com.ning.billing.mock.BrainDeadProxyFactory;
+import com.ning.billing.mock.BrainDeadProxyFactory.ZombieControl;
public class TestDefaultBillingEvent {
public static final UUID ID_ZERO = new UUID(0L,0L);
@@ -48,88 +50,88 @@ public class TestDefaultBillingEvent {
@Test(groups={"fast"})
public void testEventOrderingSubscription() {
-
+
BillingEvent event0 = createEvent(subscription(ID_ZERO), new DateTime("2012-01-31T00:02:04.000Z"), SubscriptionTransitionType.CREATE);
BillingEvent event1 = createEvent(subscription(ID_ONE), new DateTime("2012-01-31T00:02:04.000Z"), SubscriptionTransitionType.CREATE);
BillingEvent event2 = createEvent(subscription(ID_TWO), new DateTime("2012-01-31T00:02:04.000Z"), SubscriptionTransitionType.CREATE);
-
+
SortedSet<BillingEvent> set = new TreeSet<BillingEvent>();
set.add(event2);
set.add(event1);
set.add(event0);
-
+
Iterator<BillingEvent> it = set.iterator();
-
+
Assert.assertEquals(event0, it.next());
Assert.assertEquals(event1, it.next());
Assert.assertEquals(event2, it.next());
}
-
+
@Test(groups={"fast"})
public void testEventOrderingDate() {
-
+
BillingEvent event0 = createEvent(subscription(ID_ZERO), new DateTime("2012-01-01T00:02:04.000Z"), SubscriptionTransitionType.CREATE);
BillingEvent event1 = createEvent(subscription(ID_ZERO), new DateTime("2012-02-01T00:02:04.000Z"), SubscriptionTransitionType.CREATE);
BillingEvent event2 = createEvent(subscription(ID_ZERO), new DateTime("2012-03-01T00:02:04.000Z"), SubscriptionTransitionType.CREATE);
-
+
SortedSet<BillingEvent> set = new TreeSet<BillingEvent>();
set.add(event2);
set.add(event1);
set.add(event0);
-
+
Iterator<BillingEvent> it = set.iterator();
-
+
Assert.assertEquals(event0, it.next());
Assert.assertEquals(event1, it.next());
Assert.assertEquals(event2, it.next());
}
-
+
@Test(groups={"fast"})
public void testEventOrderingType() {
-
+
BillingEvent event0 = createEvent(subscription(ID_ZERO), new DateTime("2012-01-01T00:02:04.000Z"), SubscriptionTransitionType.CREATE);
BillingEvent event1 = createEvent(subscription(ID_ZERO), new DateTime("2012-01-01T00:02:04.000Z"), SubscriptionTransitionType.CHANGE);
BillingEvent event2 = createEvent(subscription(ID_ZERO), new DateTime("2012-01-01T00:02:04.000Z"), SubscriptionTransitionType.CANCEL);
-
+
SortedSet<BillingEvent> set = new TreeSet<BillingEvent>();
set.add(event2);
set.add(event1);
set.add(event0);
-
+
Iterator<BillingEvent> it = set.iterator();
-
+
Assert.assertEquals(event0, it.next());
Assert.assertEquals(event1, it.next());
Assert.assertEquals(event2, it.next());
}
-
+
@Test(groups={"fast"})
public void testEventOrderingMix() {
-
+
BillingEvent event0 = createEvent(subscription(ID_ZERO), new DateTime("2012-01-01T00:02:04.000Z"), SubscriptionTransitionType.CREATE);
BillingEvent event1 = createEvent(subscription(ID_ZERO), new DateTime("2012-01-02T00:02:04.000Z"), SubscriptionTransitionType.CHANGE);
BillingEvent event2 = createEvent(subscription(ID_ONE), new DateTime("2012-01-01T00:02:04.000Z"), SubscriptionTransitionType.CANCEL);
-
+
SortedSet<BillingEvent> set = new TreeSet<BillingEvent>();
set.add(event2);
set.add(event1);
set.add(event0);
-
+
Iterator<BillingEvent> it = set.iterator();
-
+
Assert.assertEquals(event0, it.next());
Assert.assertEquals(event1, it.next());
Assert.assertEquals(event2, it.next());
}
-
+
private BillingEvent createEvent(Subscription sub, DateTime effectiveDate, SubscriptionTransitionType type) {
InternationalPrice zeroPrice = new MockInternationalPrice(new DefaultPrice(BigDecimal.ZERO, Currency.USD));
int billCycleDay = 1;
Plan shotgun = new MockPlan();
PlanPhase shotgunMonthly = createMockMonthlyPlanPhase(null, BigDecimal.ZERO, PhaseType.TRIAL);
-
+
return new DefaultBillingEvent(sub , effectiveDate,
shotgun, shotgunMonthly,
zeroPrice, null, BillingPeriod.NO_BILLING_PERIOD, billCycleDay,
@@ -142,13 +144,11 @@ public class TestDefaultBillingEvent {
new MockInternationalPrice(new DefaultPrice(fixedRate, Currency.USD)),
BillingPeriod.MONTHLY, phaseType);
}
-
+
private Subscription subscription(final UUID id) {
- return new BrainDeadSubscription() {
- public UUID getId() {
- return id;
- }
- };
+ Subscription subscription = BrainDeadProxyFactory.createBrainDeadProxyFor(Subscription.class);
+ ((ZombieControl) subscription).addResult("getId", id);
+ return subscription;
}
}
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 55d383a..21ed6fa 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
@@ -72,7 +72,7 @@ public class TestDefaultEntitlementBillingApi {
private ArrayList<SubscriptionBundle> bundles;
private ArrayList<Subscription> subscriptions;
private ArrayList<SubscriptionTransition> transitions;
- private BrainDeadMockEntitlementDao dao;
+ private EntitlementDao dao;
private Clock clock;
private SubscriptionData subscription;
@@ -112,54 +112,21 @@ public class TestDefaultEntitlementBillingApi {
subscriptions.add(subscription);
- dao = new BrainDeadMockEntitlementDao() {
- @Override
- public List<SubscriptionBundle> getSubscriptionBundleForAccount(
- UUID accountId) {
- return bundles;
-
- }
-
- @Override
- public List<Subscription> getSubscriptions(UUID bundleId) {
- return subscriptions;
- }
-
- @Override
- public Subscription getSubscriptionFromId(UUID subscriptionId) {
- return subscription;
-
- }
-
- @Override
- public UUID getAccountIdFromSubscriptionId(final UUID subscriptionId) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public SubscriptionBundle getSubscriptionBundleFromId(UUID bundleId) {
- return bundle;
- }
- };
+ dao = BrainDeadProxyFactory.createBrainDeadProxyFor(EntitlementDao.class);
+ ((ZombieControl) dao).addResult("getSubscriptionBundleForAccount", bundles);
+ ((ZombieControl) dao).addResult("getSubscriptions", subscriptions);
+ ((ZombieControl) dao).addResult("getSubscriptionFromId", subscription);
+ ((ZombieControl) dao).addResult("getSubscriptionBundleFromId", bundle);
assertTrue(true);
}
@Test(enabled=true, groups="fast")
public void testBillingEventsEmpty() {
- EntitlementDao dao = new BrainDeadMockEntitlementDao() {
- @Override
- public List<SubscriptionBundle> getSubscriptionBundleForAccount(
- UUID accountId) {
- return new ArrayList<SubscriptionBundle>();
- }
- @Override
- public UUID getAccountIdFromSubscriptionId(final UUID subscriptionId) {
- throw new UnsupportedOperationException();
- }
+ dao = BrainDeadProxyFactory.createBrainDeadProxyFor(EntitlementDao.class);
+ ((ZombieControl) dao).addResult("getSubscriptionBundleForAccount", new ArrayList<SubscriptionBundle>());
- };
AccountUserApi accountApi = new BrainDeadAccountUserApi() ;
DefaultEntitlementBillingApi api = new DefaultEntitlementBillingApi(dao,accountApi,catalogService);
SortedSet<BillingEvent> events = api.getBillingEventsForAccount(new UUID(0L,0L));
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserCustomFieldsSql.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserCustomFieldsSql.java
new file mode 100644
index 0000000..d888c14
--- /dev/null
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserCustomFieldsSql.java
@@ -0,0 +1,174 @@
+/*
+ * 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.entitlement.api.user;
+
+import static org.testng.Assert.assertNotNull;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertTrue;
+
+import org.joda.time.DateTime;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+import com.google.inject.Stage;
+import com.ning.billing.catalog.api.BillingPeriod;
+import com.ning.billing.catalog.api.PriceListSet;
+import com.ning.billing.entitlement.api.TestApiBase;
+import com.ning.billing.entitlement.api.ApiTestListener.NextEvent;
+import com.ning.billing.entitlement.glue.MockEngineModuleSql;
+import com.ning.billing.util.customfield.CustomField;
+
+
+public class TestUserCustomFieldsSql extends TestApiBase {
+
+ @Override
+ protected Injector getInjector() {
+ return Guice.createInjector(Stage.DEVELOPMENT, new MockEngineModuleSql());
+ }
+
+
+
+ @Test(enabled=false, groups={"slow"})
+ public void stress() {
+ cleanupTest();
+ for (int i = 0; i < 20; i++) {
+ setupTest();
+ testOverwriteCustomFields();
+ cleanupTest();
+
+ setupTest();
+ testBasicCustomFields();
+ cleanupTest();
+ }
+ }
+
+ @Test(enabled=true, groups={"slow"})
+ public void testOverwriteCustomFields() {
+ log.info("Starting testCreateWithRequestedDate");
+ try {
+
+ DateTime init = clock.getUTCNow();
+ DateTime requestedDate = init.minusYears(1);
+
+ String productName = "Shotgun";
+ BillingPeriod term = BillingPeriod.MONTHLY;
+ String planSetName = PriceListSet.DEFAULT_PRICELIST_NAME;
+
+ testListener.pushExpectedEvent(NextEvent.PHASE);
+ testListener.pushExpectedEvent(NextEvent.CREATE);
+ SubscriptionData subscription = (SubscriptionData) entitlementApi.createSubscription(bundle.getId(),
+ getProductSpecifier(productName, planSetName, term, null), requestedDate);
+ assertNotNull(subscription);
+
+ assertEquals(subscription.getFieldValue("nonExistent"), null);
+
+ subscription.setFieldValue("field1", "value1");
+ assertEquals(subscription.getFieldValue("field1"), "value1");
+ List<CustomField> allFields = subscription.getFieldList();
+ assertEquals(allFields.size(), 1);
+
+ subscription.setFieldValue("field1", "valueNew1");
+ assertEquals(subscription.getFieldValue("field1"), "valueNew1");
+ allFields = subscription.getFieldList();
+ assertEquals(allFields.size(), 1);
+
+ subscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(subscription.getId());
+ assertEquals(subscription.getFieldValue("field1"), "valueNew1");
+ allFields = subscription.getFieldList();
+ assertEquals(allFields.size(), 1);
+
+ subscription.setFieldValue("field1", "valueSuperNew1");
+ assertEquals(subscription.getFieldValue("field1"), "valueSuperNew1");
+ allFields = subscription.getFieldList();
+ assertEquals(allFields.size(), 1);
+
+ subscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(subscription.getId());
+ assertEquals(subscription.getFieldValue("field1"), "valueSuperNew1");
+ allFields = subscription.getFieldList();
+ assertEquals(allFields.size(), 1);
+
+ /*
+ * BROKEN
+ subscription.setFieldValue("field1", null);
+ subscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(subscription.getId());
+ assertEquals(subscription.getFieldValue("field1"), null);
+ allFields = subscription.getFieldList();
+ assertEquals(allFields.size(), 1);
+ */
+ } catch (EntitlementUserApiException e) {
+ log.error("Unexpected exception",e);
+ Assert.fail(e.getMessage());
+ }
+ }
+
+ @Test(enabled=true, groups={"slow"})
+ public void testBasicCustomFields() {
+ log.info("Starting testCreateWithRequestedDate");
+ try {
+
+ DateTime init = clock.getUTCNow();
+ DateTime requestedDate = init.minusYears(1);
+
+ String productName = "Shotgun";
+ BillingPeriod term = BillingPeriod.MONTHLY;
+ String planSetName = PriceListSet.DEFAULT_PRICELIST_NAME;
+
+ testListener.pushExpectedEvent(NextEvent.PHASE);
+ testListener.pushExpectedEvent(NextEvent.CREATE);
+ SubscriptionData subscription = (SubscriptionData) entitlementApi.createSubscription(bundle.getId(),
+ getProductSpecifier(productName, planSetName, term, null), requestedDate);
+ assertNotNull(subscription);
+
+
+ subscription.setFieldValue("field1", "value1");
+ assertEquals(subscription.getFieldValue("field1"), "value1");
+ List<CustomField> allFields = subscription.getFieldList();
+ assertEquals(allFields.size(), 1);
+
+ subscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(subscription.getId());
+ assertEquals(subscription.getFieldValue("field1"), "value1");
+ assertEquals(allFields.size(), 1);
+
+ subscription.clearFields();
+
+ subscription.setFieldValue("field2", "value2");
+ subscription.setFieldValue("field3", "value3");
+ assertEquals(subscription.getFieldValue("field2"), "value2");
+ assertEquals(subscription.getFieldValue("field3"), "value3");
+ allFields = subscription.getFieldList();
+ assertEquals(allFields.size(), 2);
+
+ subscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(subscription.getId());
+ assertEquals(subscription.getFieldValue("field2"), "value2");
+ assertEquals(subscription.getFieldValue("field3"), "value3");
+ allFields = subscription.getFieldList();
+ assertEquals(allFields.size(), 2);
+
+ } catch (EntitlementUserApiException e) {
+ log.error("Unexpected exception",e);
+ Assert.fail(e.getMessage());
+ }
+ }
+}
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/engine/dao/MockEntitlementDaoMemory.java b/entitlement/src/test/java/com/ning/billing/entitlement/engine/dao/MockEntitlementDaoMemory.java
index fac7d62..085afb9 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/engine/dao/MockEntitlementDaoMemory.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/engine/dao/MockEntitlementDaoMemory.java
@@ -23,6 +23,8 @@ import java.util.LinkedList;
import java.util.List;
import java.util.TreeSet;
import java.util.UUID;
+
+import org.apache.commons.lang.NotImplementedException;
import org.joda.time.DateTime;
import org.skife.jdbi.v2.sqlobject.mixins.Transmogrifier;
import org.slf4j.Logger;
@@ -447,4 +449,9 @@ public class MockEntitlementDaoMemory implements EntitlementDao, MockEntitlement
}
}
+ @Override
+ public void saveCustomFields(SubscriptionData subscription) {
+ throw new NotImplementedException();
+ }
+
}
diff --git a/invoice/src/test/java/com/ning/billing/invoice/dao/InvoiceDaoTests.java b/invoice/src/test/java/com/ning/billing/invoice/dao/InvoiceDaoTests.java
index 4f936fd..b46247a 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/dao/InvoiceDaoTests.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/dao/InvoiceDaoTests.java
@@ -39,6 +39,8 @@ import com.ning.billing.invoice.model.DefaultInvoicePayment;
import com.ning.billing.invoice.model.InvoiceGenerator;
import com.ning.billing.invoice.model.InvoiceItemList;
import com.ning.billing.invoice.model.RecurringInvoiceItem;
+import com.ning.billing.mock.BrainDeadProxyFactory;
+import com.ning.billing.mock.BrainDeadProxyFactory.ZombieControl;
import com.ning.billing.util.clock.Clock;
import com.ning.billing.util.clock.DefaultClock;
import org.joda.time.DateTime;
@@ -508,7 +510,9 @@ public class InvoiceDaoTests extends InvoiceDaoTestBase {
MockPlanPhase phase1 = new MockPlanPhase(recurringPrice, null, BillingPeriod.MONTHLY, PhaseType.TRIAL);
MockPlan plan1 = new MockPlan(phase1);
- Subscription subscription = new MockSubscription();
+ Subscription subscription = BrainDeadProxyFactory.createBrainDeadProxyFor(Subscription.class);
+ ((ZombieControl) subscription).addResult("getId", UUID.randomUUID());
+
DateTime effectiveDate1 = new DateTime(2011, 2, 1, 0, 0, 0, 0);
BillingEvent event1 = new DefaultBillingEvent(subscription, effectiveDate1, plan1, phase1, null,
recurringPrice, BillingPeriod.MONTHLY, 1, BillingModeType.IN_ADVANCE,
@@ -556,7 +560,8 @@ public class InvoiceDaoTests extends InvoiceDaoTestBase {
MockPlanPhase phase = new MockPlanPhase(recurringPrice, null);
MockPlan plan = new MockPlan(phase);
- Subscription subscription = new MockSubscription();
+ Subscription subscription = BrainDeadProxyFactory.createBrainDeadProxyFor(Subscription.class);
+ ((ZombieControl) subscription).addResult("getId", UUID.randomUUID());
DateTime effectiveDate = buildDateTime(2011, 1, 1);
BillingEvent event = new DefaultBillingEvent(subscription, effectiveDate, plan, phase, null,
@@ -586,7 +591,9 @@ public class InvoiceDaoTests extends InvoiceDaoTestBase {
MockPlanPhase phase2 = new MockPlanPhase(recurringPrice, null);
MockPlan plan = new MockPlan();
- Subscription subscription = new MockSubscription();
+
+ Subscription subscription = BrainDeadProxyFactory.createBrainDeadProxyFor(Subscription.class);
+ ((ZombieControl) subscription).addResult("getId", UUID.randomUUID());
DateTime effectiveDate1 = buildDateTime(2011, 1, 1);
BillingEvent event1 = new DefaultBillingEvent(subscription, effectiveDate1, plan, phase1, fixedPrice,
@@ -643,7 +650,9 @@ public class InvoiceDaoTests extends InvoiceDaoTestBase {
MockPlanPhase phase2 = new MockPlanPhase(recurringPrice, null);
MockPlan plan = new MockPlan();
- Subscription subscription = new MockSubscription();
+
+ Subscription subscription = BrainDeadProxyFactory.createBrainDeadProxyFor(Subscription.class);
+ ((ZombieControl) subscription).addResult("getId", UUID.randomUUID());
DateTime effectiveDate1 = buildDateTime(2011, 1, 1);
BillingEvent event1 = new DefaultBillingEvent(subscription, effectiveDate1, plan, phase1, fixedPrice,
diff --git a/invoice/src/test/java/com/ning/billing/invoice/notification/TestNextBillingDateNotifier.java b/invoice/src/test/java/com/ning/billing/invoice/notification/TestNextBillingDateNotifier.java
index f6c1063..fdc5076 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/notification/TestNextBillingDateNotifier.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/notification/TestNextBillingDateNotifier.java
@@ -57,6 +57,8 @@ import com.ning.billing.entitlement.events.EntitlementEvent;
import com.ning.billing.invoice.InvoiceListener;
import com.ning.billing.invoice.dao.DefaultInvoiceDao;
import com.ning.billing.lifecycle.KillbillService.ServiceException;
+import com.ning.billing.mock.BrainDeadProxyFactory;
+import com.ning.billing.mock.BrainDeadProxyFactory.ZombieControl;
import com.ning.billing.util.bus.Bus;
import com.ning.billing.util.bus.InMemoryBus;
import com.ning.billing.util.clock.Clock;
@@ -102,135 +104,6 @@ public class TestNextBillingDateNotifier {
}
- private class MockEntitlementDao implements EntitlementDao {
-
- @Override
- public List<SubscriptionBundle> getSubscriptionBundleForAccount(
- UUID accountId) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public SubscriptionBundle getSubscriptionBundleFromKey(String bundleKey) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public SubscriptionBundle getSubscriptionBundleFromId(UUID bundleId) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public SubscriptionBundle createSubscriptionBundle(
- SubscriptionBundleData bundle) {
- throw new UnsupportedOperationException();
-
- }
-
- @Override
- public Subscription getSubscriptionFromId(UUID subscriptionId) {
- return new BrainDeadSubscription();
-
- }
-
- @Override
- public UUID getAccountIdFromSubscriptionId(UUID subscriptionId) {
- throw new UnsupportedOperationException();
-
- }
-
- @Override
- public Subscription getBaseSubscription(UUID bundleId) {
- throw new UnsupportedOperationException();
-
- }
-
- @Override
- public List<Subscription> getSubscriptions(UUID bundleId) {
- throw new UnsupportedOperationException();
-
- }
-
- @Override
- public List<Subscription> getSubscriptionsForKey(String bundleKey) {
- throw new UnsupportedOperationException();
-
- }
-
- @Override
- public void updateSubscription(SubscriptionData subscription) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void createNextPhaseEvent(UUID subscriptionId,
- EntitlementEvent nextPhase) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public EntitlementEvent getEventById(UUID eventId) {
- throw new UnsupportedOperationException();
-
- }
-
- @Override
- public List<EntitlementEvent> getEventsForSubscription(
- UUID subscriptionId) {
- throw new UnsupportedOperationException();
-
- }
-
- @Override
- public List<EntitlementEvent> getPendingEventsForSubscription(
- UUID subscriptionId) {
- throw new UnsupportedOperationException();
-
- }
-
- @Override
- public void createSubscription(SubscriptionData subscription,
- List<EntitlementEvent> initialEvents) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void cancelSubscription(UUID subscriptionId,
- EntitlementEvent cancelEvent) {
- throw new UnsupportedOperationException();
-
- }
-
- @Override
- public void uncancelSubscription(UUID subscriptionId,
- List<EntitlementEvent> uncancelEvents) {
- throw new UnsupportedOperationException();
-
- }
-
- @Override
- public void changePlan(UUID subscriptionId,
- List<EntitlementEvent> changeEvents) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void migrate(UUID acountId, AccountMigrationData data) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void undoMigration(UUID accountId) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void recreateSubscription(UUID subscriptionId,
- List<EntitlementEvent> recreateEvents) {
- throw new UnsupportedOperationException();
- }
-
- }
@BeforeClass(groups={"setup"})
public void setup() throws ServiceException, IOException, ClassNotFoundException, SQLException {
@@ -260,7 +133,13 @@ public class TestNextBillingDateNotifier {
eventBus = g.getInstance(Bus.class);
helper = g.getInstance(MysqlTestingHelper.class);
notificationQueueService = g.getInstance(NotificationQueueService.class);
- notifier = new DefaultNextBillingDateNotifier(notificationQueueService,g.getInstance(InvoiceConfig.class), new MockEntitlementDao(), listener);
+
+
+ Subscription subscription = BrainDeadProxyFactory.createBrainDeadProxyFor(Subscription.class);
+ EntitlementDao entitlementDao = BrainDeadProxyFactory.createBrainDeadProxyFor(EntitlementDao.class);
+ ((ZombieControl) entitlementDao).addResult("getSubscriptionFromId", subscription);
+
+ notifier = new DefaultNextBillingDateNotifier(notificationQueueService,g.getInstance(InvoiceConfig.class), entitlementDao, listener);
startMysql();
}
diff --git a/invoice/src/test/java/com/ning/billing/invoice/tests/DefaultInvoiceGeneratorTests.java b/invoice/src/test/java/com/ning/billing/invoice/tests/DefaultInvoiceGeneratorTests.java
index 136eeb5..e633755 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/tests/DefaultInvoiceGeneratorTests.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/tests/DefaultInvoiceGeneratorTests.java
@@ -35,13 +35,14 @@ import com.ning.billing.entitlement.api.user.SubscriptionTransition.Subscription
import com.ning.billing.invoice.api.Invoice;
import com.ning.billing.invoice.api.InvoiceApiException;
import com.ning.billing.invoice.api.InvoiceItem;
-import com.ning.billing.invoice.dao.MockSubscription;
import com.ning.billing.invoice.model.BillingEventSet;
import com.ning.billing.invoice.model.DefaultInvoiceGenerator;
import com.ning.billing.invoice.model.FixedPriceInvoiceItem;
import com.ning.billing.invoice.model.InvoiceGenerator;
import com.ning.billing.invoice.model.InvoiceItemList;
import com.ning.billing.invoice.model.RecurringInvoiceItem;
+import com.ning.billing.mock.BrainDeadProxyFactory;
+import com.ning.billing.mock.BrainDeadProxyFactory.ZombieControl;
import com.ning.billing.util.clock.Clock;
import com.ning.billing.util.clock.DefaultClock;
@@ -452,7 +453,9 @@ public class DefaultInvoiceGeneratorTests extends InvoicingTestBase {
@Test
public void testFixedPriceLifeCycle() throws InvoiceApiException {
UUID accountId = UUID.randomUUID();
- Subscription subscription = new MockSubscription();
+ Subscription subscription = BrainDeadProxyFactory.createBrainDeadProxyFor(Subscription.class);
+ ((ZombieControl) subscription).addResult("getId", UUID.randomUUID());
+
Plan plan = new MockPlan("plan 1");
MockInternationalPrice zeroPrice = new MockInternationalPrice(new DefaultPrice(ZERO, Currency.USD));
MockInternationalPrice cheapPrice = new MockInternationalPrice(new DefaultPrice(ONE, Currency.USD));
diff --git a/util/src/test/java/com/ning/billing/mock/BrainDeadProxyFactory.java b/util/src/test/java/com/ning/billing/mock/BrainDeadProxyFactory.java
index 31dcd30..2998d07 100644
--- a/util/src/test/java/com/ning/billing/mock/BrainDeadProxyFactory.java
+++ b/util/src/test/java/com/ning/billing/mock/BrainDeadProxyFactory.java
@@ -26,48 +26,48 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class BrainDeadProxyFactory {
- private static final Logger log = LoggerFactory.getLogger(BrainDeadProxyFactory.class);
+ private static final Logger log = LoggerFactory.getLogger(BrainDeadProxyFactory.class);
- public static interface ZombieControl {
-
- public ZombieControl addResult(String method, Object result);
-
- public ZombieControl clearResults();
-
- }
+ public static interface ZombieControl {
- @SuppressWarnings("unchecked")
- public static <T> T createBrainDeadProxyFor(final Class<T> clazz) {
- return (T) Proxy.newProxyInstance(clazz.getClassLoader(),
+ public ZombieControl addResult(String method, Object result);
+
+ public ZombieControl clearResults();
+
+ }
+
+ @SuppressWarnings("unchecked")
+ public static <T> T createBrainDeadProxyFor(final Class<T> clazz) {
+ return (T) Proxy.newProxyInstance(clazz.getClassLoader(),
new Class[] { clazz , ZombieControl.class},
new InvocationHandler() {
- private Map<String,Object> results = new HashMap<String,Object>();
-
- @Override
- public Object invoke(Object proxy, Method method, Object[] args)
- throws Throwable {
-
- if(method.getDeclaringClass().equals(ZombieControl.class)) {
- if(method.getName().equals("addResult")) {
- results.put((String) args[0], args[1]);
- return proxy;
- } else if(method.getName().equals("clearResults")) {
- results.clear();
- return proxy;
- }
+ private final Map<String,Object> results = new HashMap<String,Object>();
+
+ @Override
+ public Object invoke(Object proxy, Method method, Object[] args)
+ throws Throwable {
+
+ if (method.getDeclaringClass().equals(ZombieControl.class)) {
+ if(method.getName().equals("addResult")) {
+ results.put((String) args[0], args[1]);
+ return proxy;
+ } else if(method.getName().equals("clearResults")) {
+ results.clear();
+ return proxy;
+ }
+
+ } else {
- } else {
-
- Object result = results.get(method.getName());
- if (result != null) {
- return result;
- } else {
- log.error(String.format("No result for Method: '%s' on Class '%s'",method.getName(), method.getDeclaringClass().getName()));
- throw new UnsupportedOperationException();
- }
- }
- return (Void) null;
- }
- });
- }
+ Object result = results.get(method.getName());
+ if (result != null) {
+ return result;
+ } else {
+ log.error(String.format("No result for Method: '%s' on Class '%s'",method.getName(), method.getDeclaringClass().getName()));
+ throw new UnsupportedOperationException();
+ }
+ }
+ return null;
+ }
+ });
+ }
}