killbill-memoizeit
Changes
entitlement/src/main/java/com/ning/billing/entitlement/api/billing/EntitlementBillingApi.java 16(+4 -12)
entitlement/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionBuilder.java 124(+124 -0)
entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/ISubscriptionSqlDao.java 15(+12 -3)
Details
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/api/billing/EntitlementBillingApi.java b/entitlement/src/main/java/com/ning/billing/entitlement/api/billing/EntitlementBillingApi.java
index d3e3c6e..c37c79d 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/api/billing/EntitlementBillingApi.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/api/billing/EntitlementBillingApi.java
@@ -27,7 +27,7 @@ import com.ning.billing.account.api.IAccount;
import com.ning.billing.catalog.api.ICatalog;
import com.ning.billing.entitlement.api.user.ISubscription;
import com.ning.billing.entitlement.api.user.Subscription;
-import com.ning.billing.entitlement.api.user.Subscription.SubscriptionBuilder;
+import com.ning.billing.entitlement.api.user.SubscriptionBuilder;
import com.ning.billing.entitlement.engine.core.Engine;
import com.ning.billing.entitlement.engine.dao.IEntitlementDao;
import com.ning.billing.util.clock.IClock;
@@ -62,18 +62,10 @@ public class EntitlementBillingApi implements IEntitlementBillingApi {
new EntitlementBillingApiException(String.format("Unknwon subscription %s", subscriptionId));
}
- Subscription updatedSubscription = new SubscriptionBuilder()
- .setId(subscription.getId())
- .setBundleId(subscription.getBundleId())
- .setStartDate(subscription.getStartDate())
- .setBundleStartDate(subscription.getBundleStartDate())
+ SubscriptionBuilder builder = new SubscriptionBuilder(subscription)
.setChargedThroughDate(ctd)
- .setPaidThroughDate(subscription.getPaidThroughDate())
- .setActiveVersion(subscription.getActiveVersion())
- .setCategory(subscription.getCategory())
- .build();
-
- dao.updateSubscription(updatedSubscription);
+ .setPaidThroughDate(subscription.getPaidThroughDate());
+ dao.updateSubscription(new Subscription(builder, false));
}
}
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/api/user/EntitlementUserApi.java b/entitlement/src/main/java/com/ning/billing/entitlement/api/user/EntitlementUserApi.java
index decc852..df896e8 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/api/user/EntitlementUserApi.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/api/user/EntitlementUserApi.java
@@ -30,6 +30,7 @@ import com.ning.billing.catalog.api.ICatalogService;
import com.ning.billing.catalog.api.IPlan;
import com.ning.billing.catalog.api.IPlanPhase;
import com.ning.billing.catalog.api.IPriceListSet;
+import com.ning.billing.catalog.api.PlanAlignmentChange;
import com.ning.billing.entitlement.alignment.IPlanAligner;
import com.ning.billing.entitlement.alignment.IPlanAligner.TimedPhase;
import com.ning.billing.entitlement.api.user.ISubscription;
@@ -100,13 +101,11 @@ public class EntitlementUserApi implements IEntitlementUserApi {
String realPriceList = (priceList == null) ? IPriceListSet.DEFAULT_PRICELIST_NAME : priceList;
DateTime now = clock.getUTCNow();
- requestedDate = (requestedDate != null) ? Clock.truncateMs(requestedDate) : null;
+ requestedDate = (requestedDate != null) ? Clock.truncateMs(requestedDate) : now;
if (requestedDate != null && requestedDate.isAfter(now)) {
throw new EntitlementUserApiException(ErrorCode.ENT_INVALID_REQUESTED_DATE, requestedDate.toString());
}
- requestedDate = (requestedDate == null) ? now : requestedDate;
-
IPlan plan = catalogService.getCatalog().getPlan(productName, term, realPriceList);
if (plan == null) {
throw new EntitlementUserApiException(ErrorCode.ENT_CREATE_BAD_CATALOG, productName, term, realPriceList);
@@ -146,7 +145,13 @@ public class EntitlementUserApi implements IEntitlementUserApi {
}
DateTime effectiveDate = requestedDate;
- Subscription subscription = new Subscription(bundleId, plan.getProduct().getCategory(), bundleStartDate, effectiveDate);
+ Subscription subscription = new Subscription(new SubscriptionBuilder()
+ .setId(UUID.randomUUID())
+ .setBundleId(bundleId)
+ .setCategory(plan.getProduct().getCategory())
+ .setBundleStartDate(bundleStartDate)
+ .setStartDate(effectiveDate),
+ false);
TimedPhase currentTimedPhase = planAligner.getCurrentTimedPhaseOnCreate(subscription, plan, realPriceList, effectiveDate);
ApiEventCreate creationEvent =
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/api/user/Subscription.java b/entitlement/src/main/java/com/ning/billing/entitlement/api/user/Subscription.java
index 3781e74..950af53 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/api/user/Subscription.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/api/user/Subscription.java
@@ -16,7 +16,6 @@
package com.ning.billing.entitlement.api.user;
-import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
@@ -24,10 +23,10 @@ import java.util.LinkedList;
import java.util.List;
import java.util.UUID;
-import com.ning.billing.ErrorCode;
-import com.ning.billing.account.api.IAccount;
import org.joda.time.DateTime;
+import com.ning.billing.ErrorCode;
+
import com.ning.billing.catalog.api.ActionPolicy;
import com.ning.billing.catalog.api.BillingPeriod;
import com.ning.billing.catalog.api.CatalogApiException;
@@ -60,118 +59,55 @@ import com.ning.billing.util.clock.IClock;
public class Subscription extends PrivateFields implements ISubscription {
+ //
+ // Singletons used to perform API changes
+ private final IClock clock;
+ private final IEntitlementDao dao;
+ private final ICatalog catalog;
+ private final IPlanAligner planAligner;
+
+ //
+ // Final subscription fields
+ //
private final UUID id;
private final UUID bundleId;
private final DateTime startDate;
private final DateTime bundleStartDate;
- private final long activeVersion;
private final ProductCategory category;
- private final IClock clock;
- private final IEntitlementDao dao;
- private final ICatalog catalog;
- private final IPlanAligner planAligner;
-
- // STEPH interaction with billing /payment system
+ //
+ // Those can be modified through non User APIs, and a new Subscription object would be created
+ //
+ private final long activeVersion;
private final DateTime chargedThroughDate;
private final DateTime paidThroughDate;
- // STEPH non final because of change/ cancel API at the object level
+ //
+ // User APIs (createm chnage, cancel,...) will recompute those each time,
+ // so the user holding that subscription object get the correct state when
+ // the call completes
+ //
private List<SubscriptionTransition> transitions;
-
- public static class SubscriptionBuilder {
- private UUID id;
- private UUID bundleId;
- private DateTime startDate;
- private DateTime bundleStartDate;
- private Long activeVersion;
- private ProductCategory category;
- private DateTime chargedThroughDate;
- private DateTime paidThroughDate;
-
- public SubscriptionBuilder setId(UUID id) {
- this.id = id;
- return this;
- }
- public SubscriptionBuilder setBundleId(UUID bundleId) {
- this.bundleId = bundleId;
- return this;
- }
- public SubscriptionBuilder setStartDate(DateTime startDate) {
- this.startDate = startDate;
- return this;
- }
- public SubscriptionBuilder setBundleStartDate(DateTime bundleStartDate) {
- this.bundleStartDate = bundleStartDate;
- return this;
- }
- public SubscriptionBuilder setActiveVersion(long activeVersion) {
- this.activeVersion = activeVersion;
- return this;
- }
- public SubscriptionBuilder setChargedThroughDate(DateTime chargedThroughDate) {
- this.chargedThroughDate = chargedThroughDate;
- return this;
- }
- public SubscriptionBuilder setPaidThroughDate(DateTime paidThroughDate) {
- this.paidThroughDate = paidThroughDate;
- return this;
- }
- public SubscriptionBuilder setCategory(ProductCategory category) {
- this.category = category;
- return this;
- }
-
- private void checkAllFieldsSet() {
- for (Field cur : SubscriptionBuilder.class.getDeclaredFields()) {
- try {
- Object value = cur.get(this);
- if (value == null) {
- throw new EntitlementError(String.format("Field %s has not been set for Subscription",
- cur.getName()));
- }
- } catch (IllegalAccessException e) {
- throw new EntitlementError(String.format("Failed to access value for field %s for Subscription",
- cur.getName()), e);
- }
- }
- }
-
- public Subscription build() {
- //checkAllFieldsSet();
- return new Subscription(id, bundleId, category, bundleStartDate, startDate, chargedThroughDate, paidThroughDate, activeVersion);
- }
-
- }
-
- public Subscription(UUID bundleId, ProductCategory category, DateTime bundleStartDate, DateTime startDate) {
- this(UUID.randomUUID(), bundleId, category, bundleStartDate, startDate, null, null, SubscriptionEvents.INITIAL_VERSION);
- }
-
-
- public Subscription(UUID id, UUID bundleId, ProductCategory category, DateTime bundleStartDate, DateTime startDate, DateTime ctd, DateTime ptd, long activeVersion) {
-
+ public Subscription(SubscriptionBuilder builder, boolean rebuildTransition) {
super();
this.clock = InjectorMagic.getClock();
this.dao = InjectorMagic.getEntitlementDao();
this.catalog = InjectorMagic.getCatlog();
this.planAligner = InjectorMagic.getPlanAligner();
- this.id = id;
- this.bundleId = bundleId;
- this.startDate = startDate;
- this.bundleStartDate = bundleStartDate;
- this.category = category;
-
- this.activeVersion = activeVersion;
-
- this.chargedThroughDate = ctd;
- this.paidThroughDate = ptd;
-
- rebuildTransitions();
+ this.id = builder.getId();
+ this.bundleId = builder.getBundleId();
+ this.startDate = builder.getStartDate();
+ this.bundleStartDate = builder.getBundleStartDate();
+ this.category = builder.getCategory();
+ this.activeVersion = builder.getActiveVersion();
+ this.chargedThroughDate = builder.getChargedThroughDate();
+ this.paidThroughDate = builder.getPaidThroughDate();
+ if (rebuildTransition) {
+ rebuildTransitions();
+ }
}
-
@Override
public UUID getId() {
return id;
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionBuilder.java b/entitlement/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionBuilder.java
new file mode 100644
index 0000000..d14b754
--- /dev/null
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionBuilder.java
@@ -0,0 +1,124 @@
+/*
+ * 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 java.lang.reflect.Field;
+import java.util.UUID;
+
+import org.joda.time.DateTime;
+
+import com.ning.billing.catalog.api.ProductCategory;
+import com.ning.billing.entitlement.exceptions.EntitlementError;
+
+public class SubscriptionBuilder {
+
+ private UUID id;
+ private UUID bundleId;
+ private DateTime startDate;
+ private DateTime bundleStartDate;
+ private Long activeVersion;
+ private ProductCategory category;
+ private DateTime chargedThroughDate;
+ private DateTime paidThroughDate;
+
+ public SubscriptionBuilder() {
+ this.activeVersion = SubscriptionEvents.INITIAL_VERSION;
+ }
+
+ public SubscriptionBuilder(Subscription original) {
+ this.id = original.getId();
+ this.bundleId = original.getBundleId();
+ this.startDate = original.getStartDate();
+ this.bundleStartDate = original.getBundleStartDate();
+ this.category = original.getCategory();
+ this.activeVersion = original.getActiveVersion();
+ this.chargedThroughDate = original.getChargedThroughDate();
+ this.paidThroughDate = original.getPaidThroughDate();
+ }
+
+ public SubscriptionBuilder setId(UUID id) {
+ this.id = id;
+ return this;
+ }
+ public SubscriptionBuilder setBundleId(UUID bundleId) {
+ this.bundleId = bundleId;
+ return this;
+ }
+ public SubscriptionBuilder setStartDate(DateTime startDate) {
+ this.startDate = startDate;
+ return this;
+ }
+ public SubscriptionBuilder setBundleStartDate(DateTime bundleStartDate) {
+ this.bundleStartDate = bundleStartDate;
+ return this;
+ }
+ public SubscriptionBuilder setActiveVersion(long activeVersion) {
+ this.activeVersion = activeVersion;
+ return this;
+ }
+ public SubscriptionBuilder setChargedThroughDate(DateTime chargedThroughDate) {
+ this.chargedThroughDate = chargedThroughDate;
+ return this;
+ }
+ public SubscriptionBuilder setPaidThroughDate(DateTime paidThroughDate) {
+ this.paidThroughDate = paidThroughDate;
+ return this;
+ }
+ public SubscriptionBuilder setCategory(ProductCategory category) {
+ this.category = category;
+ return this;
+ }
+
+ public UUID getId() {
+ return id;
+ }
+ public UUID getBundleId() {
+ return bundleId;
+ }
+ public DateTime getStartDate() {
+ return startDate;
+ }
+ public DateTime getBundleStartDate() {
+ return bundleStartDate;
+ }
+ public Long getActiveVersion() {
+ return activeVersion;
+ }
+ public ProductCategory getCategory() {
+ return category;
+ }
+ public DateTime getChargedThroughDate() {
+ return chargedThroughDate;
+ }
+ public DateTime getPaidThroughDate() {
+ return paidThroughDate;
+ }
+ private void checkAllFieldsSet() {
+ for (Field cur : SubscriptionBuilder.class.getDeclaredFields()) {
+ try {
+ Object value = cur.get(this);
+ if (value == null) {
+ throw new EntitlementError(String.format("Field %s has not been set for Subscription",
+ cur.getName()));
+ }
+ } catch (IllegalAccessException e) {
+ throw new EntitlementError(String.format("Failed to access value for field %s for Subscription",
+ cur.getName()), e);
+ }
+ }
+ }
+}
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 b490fcd..943a0dc 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
@@ -37,6 +37,7 @@ import com.ning.billing.config.IEntitlementConfig;
import com.ning.billing.entitlement.api.user.ISubscription;
import com.ning.billing.entitlement.api.user.ISubscriptionBundle;
import com.ning.billing.entitlement.api.user.Subscription;
+import com.ning.billing.entitlement.api.user.SubscriptionBuilder;
import com.ning.billing.entitlement.api.user.SubscriptionBundle;
import com.ning.billing.entitlement.events.IEvent;
import com.ning.billing.entitlement.events.IEvent.EventType;
@@ -225,8 +226,7 @@ public class EntitlementDao implements IEntitlementDao {
return null;
}
});
- return new Subscription(subscription.getId(), subscription.getBundleId(),subscription.getCategory(), subscription.getBundleStartDate(),
- subscription.getStartDate(), subscription.getChargedThroughDate(), subscription.getPaidThroughDate(), subscription.getActiveVersion());
+ return new Subscription(new SubscriptionBuilder(subscription), true);
}
@Override
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/ISubscriptionSqlDao.java b/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/ISubscriptionSqlDao.java
index e1af556..f3c5c7d 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/ISubscriptionSqlDao.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/ISubscriptionSqlDao.java
@@ -41,6 +41,8 @@ import org.skife.jdbi.v2.tweak.ResultSetMapper;
import com.ning.billing.catalog.api.ProductCategory;
import com.ning.billing.entitlement.api.user.ISubscription;
import com.ning.billing.entitlement.api.user.Subscription;
+import com.ning.billing.entitlement.api.user.SubscriptionBuilder;
+
@ExternalizedSqlViaStringTemplate3()
public interface ISubscriptionSqlDao extends Transactional<ISubscriptionSqlDao>, CloseMe, Transmogrifier {
@@ -98,10 +100,17 @@ public interface ISubscriptionSqlDao extends Transactional<ISubscriptionSqlDao>,
DateTime ptd = getDate(r, "ptd_dt");
long activeVersion = r.getLong("active_version");
- Subscription subscription = new Subscription(id, bundleId, category, bundleStartDate, startDate, ctd, ptd, activeVersion);
+ Subscription subscription = new Subscription(new SubscriptionBuilder()
+ .setId(id)
+ .setBundleId(bundleId)
+ .setCategory(category)
+ .setBundleStartDate(bundleStartDate)
+ .setStartDate(startDate)
+ .setActiveVersion(activeVersion)
+ .setChargedThroughDate(ctd)
+ .setPaidThroughDate(ptd),
+ true);
return subscription;
}
}
-
-
}
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/engine/dao/EntitlementDaoMemoryMock.java b/entitlement/src/test/java/com/ning/billing/entitlement/engine/dao/EntitlementDaoMemoryMock.java
index c6fff2f..e4d2559 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/engine/dao/EntitlementDaoMemoryMock.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/engine/dao/EntitlementDaoMemoryMock.java
@@ -36,6 +36,7 @@ import com.ning.billing.config.IEntitlementConfig;
import com.ning.billing.entitlement.api.user.ISubscription;
import com.ning.billing.entitlement.api.user.ISubscriptionBundle;
import com.ning.billing.entitlement.api.user.Subscription;
+import com.ning.billing.entitlement.api.user.SubscriptionBuilder;
import com.ning.billing.entitlement.api.user.SubscriptionBundle;
import com.ning.billing.entitlement.events.IEvent;
import com.ning.billing.entitlement.events.IEvent.EventType;
@@ -227,8 +228,7 @@ public class EntitlementDaoMemoryMock implements IEntitlementDao, IEntitlementDa
}
private ISubscription buildSubscription(Subscription in) {
- return new Subscription(in.getId(), in.getBundleId(), in.getCategory(), in.getBundleStartDate(),
- in.getStartDate(), in.getChargedThroughDate(), in.getPaidThroughDate(), in.getActiveVersion());
+ return new Subscription(new SubscriptionBuilder(in), true);
}
@Override