diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/AuditedEntitlementDao.java b/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/AuditedEntitlementDao.java
index 38bf0ca..2d7f212 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/AuditedEntitlementDao.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/AuditedEntitlementDao.java
@@ -17,7 +17,6 @@
package com.ning.billing.entitlement.engine.dao;
import javax.annotation.Nullable;
-
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
@@ -90,10 +89,8 @@ public class AuditedEntitlementDao implements EntitlementDao {
private final Bus eventBus;
@Inject
- public AuditedEntitlementDao(final IDBI dbi, final Clock clock,
- final AddonUtils addonUtils, final NotificationQueueService notificationQueueService,
- final Bus eventBus) {
-
+ public AuditedEntitlementDao(final IDBI dbi, final Clock clock, final AddonUtils addonUtils,
+ final NotificationQueueService notificationQueueService, final Bus eventBus) {
this.clock = clock;
this.subscriptionsDao = dbi.onDemand(SubscriptionSqlDao.class);
this.eventsDao = dbi.onDemand(EntitlementEventSqlDao.class);
@@ -109,8 +106,7 @@ public class AuditedEntitlementDao implements EntitlementDao {
}
@Override
- public List<SubscriptionBundle> getSubscriptionBundleForAccount(
- final UUID accountId) {
+ public List<SubscriptionBundle> getSubscriptionBundleForAccount(final UUID accountId) {
return bundlesDao.getBundleFromAccount(accountId.toString());
}
@@ -179,18 +175,17 @@ public class AuditedEntitlementDao implements EntitlementDao {
if (bundle == null) {
return Collections.emptyList();
}
+
return getSubscriptions(factory, bundle.getId());
}
@Override
public void updateChargedThroughDate(final SubscriptionData subscription, final CallContext context) {
-
final Date ctd = (subscription.getChargedThroughDate() != null) ? subscription.getChargedThroughDate().toDate() : null;
subscriptionsDao.inTransaction(new Transaction<Void, SubscriptionSqlDao>() {
@Override
- public Void inTransaction(final SubscriptionSqlDao transactionalDao,
- final TransactionStatus status) throws Exception {
+ public Void inTransaction(final SubscriptionSqlDao transactionalDao, final TransactionStatus status) throws Exception {
final String subscriptionId = subscription.getId().toString();
transactionalDao.updateChargedThroughDate(subscription.getId().toString(), ctd, context);
final Long subscriptionRecordId = transactionalDao.getRecordId(subscriptionId);
@@ -200,10 +195,11 @@ public class AuditedEntitlementDao implements EntitlementDao {
final BundleSqlDao bundleSqlDao = transactionalDao.become(BundleSqlDao.class);
final String bundleId = subscription.getBundleId().toString();
bundleSqlDao.updateBundleLastSysTime(bundleId, clock.getUTCNow().toDate());
- // SubscriptionBundle bundle = bundleSqlDao.getById(bundleId);
+
final Long recordId = bundleSqlDao.getRecordId(bundleId);
final EntityAudit bundleAudit = new EntityAudit(TableName.BUNDLES, recordId, ChangeType.UPDATE);
bundleSqlDao.insertAuditFromTransaction(bundleAudit, context);
+
return null;
}
});
@@ -222,8 +218,9 @@ public class AuditedEntitlementDao implements EntitlementDao {
transactional.insertAuditFromTransaction(audit, context);
recordFutureNotificationFromTransaction(transactional,
- nextPhase.getEffectiveDate(),
- new EntitlementNotificationKey(nextPhase.getId()));
+ nextPhase.getEffectiveDate(),
+ new EntitlementNotificationKey(nextPhase.getId()));
+
return null;
}
});
@@ -244,17 +241,19 @@ public class AuditedEntitlementDao implements EntitlementDao {
return subscriptionsDao.inTransaction(new Transaction<Map<UUID, List<EntitlementEvent>>, SubscriptionSqlDao>() {
@Override
public Map<UUID, List<EntitlementEvent>> inTransaction(final SubscriptionSqlDao transactional,
- final TransactionStatus status) throws Exception {
+ final TransactionStatus status) throws Exception {
final List<Subscription> subscriptions = transactional.getSubscriptionsFromBundleId(bundleId.toString());
if (subscriptions.size() == 0) {
return Collections.emptyMap();
}
+
final EntitlementEventSqlDao eventsDaoFromSameTransaction = transactional.become(EntitlementEventSqlDao.class);
final Map<UUID, List<EntitlementEvent>> result = new HashMap<UUID, List<EntitlementEvent>>();
for (final Subscription cur : subscriptions) {
final List<EntitlementEvent> events = eventsDaoFromSameTransaction.getEventsForSubscription(cur.getId().toString());
result.put(cur.getId(), events);
}
+
return result;
}
});
@@ -267,16 +266,12 @@ public class AuditedEntitlementDao implements EntitlementDao {
}
@Override
- public void createSubscription(final SubscriptionData subscription,
- final List<EntitlementEvent> initialEvents, final CallContext context) {
-
+ public void createSubscription(final SubscriptionData subscription, final List<EntitlementEvent> initialEvents, final CallContext context) {
subscriptionsDao.inTransaction(new Transaction<Void, SubscriptionSqlDao>() {
-
@Override
- public Void inTransaction(final SubscriptionSqlDao transactional,
- final TransactionStatus status) throws Exception {
-
+ public Void inTransaction(final SubscriptionSqlDao transactional, final TransactionStatus status) throws Exception {
transactional.insertSubscription(subscription, context);
+
final Long subscriptionRecordId = transactional.getRecordId(subscription.getId().toString());
final EntityAudit audit = new EntityAudit(TableName.SUBSCRIPTIONS, subscriptionRecordId, ChangeType.INSERT);
transactional.insertAuditFromTransaction(audit, context);
@@ -290,8 +285,8 @@ public class AuditedEntitlementDao implements EntitlementDao {
final Long recordId = eventsDaoFromSameTransaction.getRecordId(cur.getId().toString());
audits.add(new EntityAudit(TableName.SUBSCRIPTION_EVENTS, recordId, ChangeType.INSERT));
recordFutureNotificationFromTransaction(transactional,
- cur.getEffectiveDate(),
- new EntitlementNotificationKey(cur.getId()));
+ cur.getEffectiveDate(),
+ new EntitlementNotificationKey(cur.getId()));
}
eventsDaoFromSameTransaction.insertAuditFromTransaction(audits, context);
@@ -301,22 +296,19 @@ public class AuditedEntitlementDao implements EntitlementDao {
}
@Override
- public void recreateSubscription(final UUID subscriptionId,
- final List<EntitlementEvent> recreateEvents, final CallContext context) {
-
+ public void recreateSubscription(final UUID subscriptionId, final List<EntitlementEvent> recreateEvents, final CallContext context) {
eventsDao.inTransaction(new Transaction<Void, EntitlementEventSqlDao>() {
@Override
public Void inTransaction(final EntitlementEventSqlDao transactional,
- final TransactionStatus status) throws Exception {
-
+ final TransactionStatus status) throws Exception {
final List<EntityAudit> audits = new ArrayList<EntityAudit>();
for (final EntitlementEvent cur : recreateEvents) {
transactional.insertEvent(cur, context);
final Long recordId = transactional.getRecordId(cur.getId().toString());
audits.add(new EntityAudit(TableName.SUBSCRIPTION_EVENTS, recordId, ChangeType.INSERT));
recordFutureNotificationFromTransaction(transactional,
- cur.getEffectiveDate(),
- new EntitlementNotificationKey(cur.getId()));
+ cur.getEffectiveDate(),
+ new EntitlementNotificationKey(cur.getId()));
}
@@ -328,11 +320,9 @@ public class AuditedEntitlementDao implements EntitlementDao {
@Override
public void cancelSubscription(final UUID subscriptionId, final EntitlementEvent cancelEvent, final CallContext context, final int seqId) {
-
eventsDao.inTransaction(new Transaction<Void, EntitlementEventSqlDao>() {
@Override
- public Void inTransaction(final EntitlementEventSqlDao transactional,
- final TransactionStatus status) throws Exception {
+ public Void inTransaction(final EntitlementEventSqlDao transactional, final TransactionStatus status) throws Exception {
cancelNextCancelEventFromTransaction(subscriptionId, transactional, context);
cancelNextChangeEventFromTransaction(subscriptionId, transactional, context);
cancelNextPhaseEventFromTransaction(subscriptionId, transactional, context);
@@ -344,8 +334,8 @@ public class AuditedEntitlementDao implements EntitlementDao {
transactional.insertAuditFromTransaction(audit, context);
recordFutureNotificationFromTransaction(transactional,
- cancelEvent.getEffectiveDate(),
- new EntitlementNotificationKey(cancelEvent.getId(), seqId));
+ cancelEvent.getEffectiveDate(),
+ new EntitlementNotificationKey(cancelEvent.getId(), seqId));
return null;
}
});
@@ -353,13 +343,9 @@ public class AuditedEntitlementDao implements EntitlementDao {
@Override
public void uncancelSubscription(final UUID subscriptionId, final List<EntitlementEvent> uncancelEvents, final CallContext context) {
-
eventsDao.inTransaction(new Transaction<Void, EntitlementEventSqlDao>() {
-
@Override
- public Void inTransaction(final EntitlementEventSqlDao transactional,
- final TransactionStatus status) throws Exception {
-
+ public Void inTransaction(final EntitlementEventSqlDao transactional, final TransactionStatus status) throws Exception {
EntitlementEvent cancelledEvent = null;
final Date now = clock.getUTCNow().toDate();
final List<EntitlementEvent> events = transactional.getFutureActiveEventForSubscription(subscriptionId.toString(), now);
@@ -386,8 +372,8 @@ public class AuditedEntitlementDao implements EntitlementDao {
final Long recordId = transactional.getRecordId(cur.getId().toString());
eventAudits.add(new EntityAudit(TableName.SUBSCRIPTION_EVENTS, recordId, ChangeType.INSERT));
recordFutureNotificationFromTransaction(transactional,
- cur.getEffectiveDate(),
- new EntitlementNotificationKey(cur.getId()));
+ cur.getEffectiveDate(),
+ new EntitlementNotificationKey(cur.getId()));
}
transactional.insertAuditFromTransaction(eventAudits, context);
@@ -412,8 +398,8 @@ public class AuditedEntitlementDao implements EntitlementDao {
eventAudits.add(new EntityAudit(TableName.SUBSCRIPTION_EVENTS, recordId, ChangeType.INSERT));
recordFutureNotificationFromTransaction(transactional,
- cur.getEffectiveDate(),
- new EntitlementNotificationKey(cur.getId()));
+ cur.getEffectiveDate(),
+ new EntitlementNotificationKey(cur.getId()));
}
transactional.insertAuditFromTransaction(eventAudits, context);
@@ -434,10 +420,8 @@ public class AuditedEntitlementDao implements EntitlementDao {
cancelFutureEventFromTransaction(subscriptionId, dao, EventType.API_USER, ApiEventType.CANCEL, context);
}
- private void cancelFutureEventFromTransaction(final UUID subscriptionId, final EntitlementEventSqlDao dao,
- final EventType type, @Nullable final ApiEventType apiType,
- final CallContext context) {
-
+ private void cancelFutureEventFromTransaction(final UUID subscriptionId, final EntitlementEventSqlDao dao, final EventType type,
+ @Nullable final ApiEventType apiType, final CallContext context) {
EntitlementEvent futureEvent = null;
final Date now = clock.getUTCNow().toDate();
final List<EntitlementEvent> events = dao.getFutureActiveEventForSubscription(subscriptionId.toString(), now);
@@ -445,9 +429,8 @@ public class AuditedEntitlementDao implements EntitlementDao {
if (cur.getType() == type &&
(apiType == null || apiType == ((ApiEvent) cur).getEventType())) {
if (futureEvent != null) {
- throw new EntitlementError(
- String.format("Found multiple future events for type %s for subscriptions %s",
- type, subscriptionId.toString()));
+ throw new EntitlementError(String.format("Found multiple future events for type %s for subscriptions %s",
+ type, subscriptionId.toString()));
}
futureEvent = cur;
}
@@ -466,6 +449,7 @@ public class AuditedEntitlementDao implements EntitlementDao {
if (input == null) {
return null;
}
+
final List<Subscription> bundleInput = new ArrayList<Subscription>();
if (input.getCategory() == ProductCategory.ADD_ON) {
final Subscription baseSubscription = getBaseSubscription(factory, input.getBundleId(), false);
@@ -474,19 +458,22 @@ public class AuditedEntitlementDao implements EntitlementDao {
} else {
bundleInput.add(input);
}
+
final List<Subscription> reloadedSubscriptions = buildBundleSubscriptions(factory, bundleInput);
for (final Subscription cur : reloadedSubscriptions) {
if (cur.getId().equals(input.getId())) {
return cur;
}
}
- throw new EntitlementError(String.format("Unexpected code path in buildSubscription"));
+
+ throw new EntitlementError("Unexpected code path in buildSubscription");
}
private List<Subscription> buildBundleSubscriptions(final SubscriptionFactory factory, final List<Subscription> input) {
if (input == null || input.size() == 0) {
return Collections.emptyList();
}
+
// Make sure BasePlan -- if exists-- is first
Collections.sort(input, new Comparator<Subscription>() {
@Override
@@ -504,67 +491,63 @@ public class AuditedEntitlementDao implements EntitlementDao {
EntitlementEvent futureBaseEvent = null;
final List<Subscription> result = new ArrayList<Subscription>(input.size());
for (final Subscription cur : input) {
-
final List<EntitlementEvent> events = eventsDao.getEventsForSubscription(cur.getId().toString());
Subscription reloaded = factory.createSubscription(new SubscriptionBuilder((SubscriptionData) cur), events);
switch (cur.getCategory()) {
- case BASE:
- final Collection<EntitlementEvent> futureApiEvents = Collections2.filter(events, new Predicate<EntitlementEvent>() {
- @Override
- public boolean apply(final EntitlementEvent input) {
- return (input.getEffectiveDate().isAfter(clock.getUTCNow()) &&
- ((input instanceof ApiEventCancel) || (input instanceof ApiEventChange)));
- }
- });
- futureBaseEvent = (futureApiEvents.size() == 0) ? null : futureApiEvents.iterator().next();
- break;
-
- case ADD_ON:
- final Plan targetAddOnPlan = reloaded.getCurrentPlan();
- final String baseProductName = (futureBaseEvent instanceof ApiEventChange) ?
- ((ApiEventChange) futureBaseEvent).getEventPlan() : null;
-
- final boolean createCancelEvent = (futureBaseEvent != null) &&
- ((futureBaseEvent instanceof ApiEventCancel) ||
- ((!addonUtils.isAddonAvailableFromPlanName(baseProductName, futureBaseEvent.getEffectiveDate(), targetAddOnPlan)) ||
- (addonUtils.isAddonIncludedFromPlanName(baseProductName, futureBaseEvent.getEffectiveDate(), targetAddOnPlan))));
-
- if (createCancelEvent) {
- final DateTime now = clock.getUTCNow();
- final EntitlementEvent addOnCancelEvent = new ApiEventCancel(new ApiEventBuilder()
- .setSubscriptionId(reloaded.getId())
- .setActiveVersion(((SubscriptionData) reloaded).getActiveVersion())
- .setProcessedDate(now)
- .setEffectiveDate(futureBaseEvent.getEffectiveDate())
- .setRequestedDate(now)
- // This event is only there to indicate the ADD_ON is future canceled, but it is not there
- // on disk until the base plan cancellation becomes effective
- .setFromDisk(false));
-
- events.add(addOnCancelEvent);
- // Finally reload subscription with full set of events
- reloaded = factory.createSubscription(new SubscriptionBuilder((SubscriptionData) cur), events);
+ case BASE:
+ final Collection<EntitlementEvent> futureApiEvents = Collections2.filter(events, new Predicate<EntitlementEvent>() {
+ @Override
+ public boolean apply(final EntitlementEvent input) {
+ return (input.getEffectiveDate().isAfter(clock.getUTCNow()) &&
+ ((input instanceof ApiEventCancel) || (input instanceof ApiEventChange)));
}
- break;
- default:
- break;
+ });
+ futureBaseEvent = (futureApiEvents.size() == 0) ? null : futureApiEvents.iterator().next();
+ break;
+
+ case ADD_ON:
+ final Plan targetAddOnPlan = reloaded.getCurrentPlan();
+ final String baseProductName = (futureBaseEvent instanceof ApiEventChange) ?
+ ((ApiEventChange) futureBaseEvent).getEventPlan() : null;
+
+ final boolean createCancelEvent = (futureBaseEvent != null) &&
+ ((futureBaseEvent instanceof ApiEventCancel) ||
+ ((!addonUtils.isAddonAvailableFromPlanName(baseProductName, futureBaseEvent.getEffectiveDate(), targetAddOnPlan)) ||
+ (addonUtils.isAddonIncludedFromPlanName(baseProductName, futureBaseEvent.getEffectiveDate(), targetAddOnPlan))));
+
+ if (createCancelEvent) {
+ final DateTime now = clock.getUTCNow();
+ final EntitlementEvent addOnCancelEvent = new ApiEventCancel(new ApiEventBuilder()
+ .setSubscriptionId(reloaded.getId())
+ .setActiveVersion(((SubscriptionData) reloaded).getActiveVersion())
+ .setProcessedDate(now)
+ .setEffectiveDate(futureBaseEvent.getEffectiveDate())
+ .setRequestedDate(now)
+ // This event is only there to indicate the ADD_ON is future canceled, but it is not there
+ // on disk until the base plan cancellation becomes effective
+ .setFromDisk(false));
+
+ events.add(addOnCancelEvent);
+ // Finally reload subscription with full set of events
+ reloaded = factory.createSubscription(new SubscriptionBuilder((SubscriptionData) cur), events);
+ }
+ break;
+ default:
+ break;
}
result.add(reloaded);
}
+
return result;
}
@Override
public void migrate(final UUID accountId, final AccountMigrationData accountData, final CallContext context) {
-
eventsDao.inTransaction(new Transaction<Void, EntitlementEventSqlDao>() {
-
@Override
- public Void inTransaction(final EntitlementEventSqlDao transactional,
- final TransactionStatus status) throws Exception {
-
+ public Void inTransaction(final EntitlementEventSqlDao transactional, final TransactionStatus status) throws Exception {
final SubscriptionSqlDao transSubDao = transactional.become(SubscriptionSqlDao.class);
final BundleSqlDao transBundleDao = transactional.become(BundleSqlDao.class);
@@ -584,8 +567,8 @@ public class AuditedEntitlementDao implements EntitlementDao {
audits.add(new EntityAudit(TableName.SUBSCRIPTION_EVENTS, recordId, ChangeType.INSERT));
recordFutureNotificationFromTransaction(transactional,
- curEvent.getEffectiveDate(),
- new EntitlementNotificationKey(curEvent.getId()));
+ curEvent.getEffectiveDate(),
+ new EntitlementNotificationKey(curEvent.getId()));
}
transSubDao.insertSubscription(subData, context);
recordId = transSubDao.getRecordId(subData.getId().toString());
@@ -606,11 +589,8 @@ public class AuditedEntitlementDao implements EntitlementDao {
public void repair(final UUID accountId, final UUID bundleId, final List<SubscriptionDataRepair> inRepair, final CallContext context) {
subscriptionsDao.inTransaction(new Transaction<Void, SubscriptionSqlDao>() {
-
@Override
- public Void inTransaction(final SubscriptionSqlDao transactional,
- final TransactionStatus status) throws Exception {
-
+ public Void inTransaction(final SubscriptionSqlDao transactional, final TransactionStatus status) throws Exception {
final EntitlementEventSqlDao transEventDao = transactional.become(EntitlementEventSqlDao.class);
for (final SubscriptionDataRepair cur : inRepair) {
transactional.updateForRepair(cur.getId().toString(), cur.getActiveVersion(), cur.getStartDate().toDate(), cur.getBundleStartDate().toDate(), context);
@@ -621,17 +601,19 @@ public class AuditedEntitlementDao implements EntitlementDao {
transEventDao.insertEvent(event, context);
if (event.getEffectiveDate().isAfter(clock.getUTCNow())) {
recordFutureNotificationFromTransaction(transactional,
- event.getEffectiveDate(),
- new EntitlementNotificationKey(event.getId()));
+ event.getEffectiveDate(),
+ new EntitlementNotificationKey(event.getId()));
}
}
}
+
try {
final RepairEntitlementEvent busEvent = new DefaultRepairEntitlementEvent(context.getUserToken(), accountId, bundleId, clock.getUTCNow());
eventBus.postFromTransaction(busEvent, transactional);
} catch (EventBusException e) {
log.warn("Failed to post repair entitlement event for bundle " + bundleId, e);
}
+
return null;
}
});
@@ -644,13 +626,14 @@ public class AuditedEntitlementDao implements EntitlementDao {
return rebuildSubscription ? buildSubscription(factory, cur) : cur;
}
}
+
return null;
}
private void recordFutureNotificationFromTransaction(final Transmogrifier transactionalDao, final DateTime effectiveDate, final NotificationKey notificationKey) {
try {
final NotificationQueue subscriptionEventQueue = notificationQueueService.getNotificationQueue(Engine.ENTITLEMENT_SERVICE_NAME,
- Engine.NOTIFICATION_QUEUE_NAME);
+ Engine.NOTIFICATION_QUEUE_NAME);
subscriptionEventQueue.recordFutureNotificationFromTransaction(transactionalDao, effectiveDate, notificationKey);
} catch (NoSuchNotificationQueue e) {
throw new RuntimeException(e);