killbill-memoizeit
Changes
entitlement/src/main/java/org/killbill/billing/entitlement/engine/core/EventsStreamBuilder.java 30(+4 -26)
entitlement/src/test/java/org/killbill/billing/entitlement/engine/core/TestEntitlementUtils.java 3(+3 -0)
junction/src/main/java/org/killbill/billing/junction/plumbing/billing/DefaultInternalBillingApi.java 2(+1 -1)
pom.xml 2(+1 -1)
subscription/src/main/java/org/killbill/billing/subscription/api/SubscriptionApiBase.java 37(+17 -20)
subscription/src/main/java/org/killbill/billing/subscription/api/svcs/DefaultSubscriptionBaseCreateApi.java 5(+3 -2)
subscription/src/main/java/org/killbill/billing/subscription/api/svcs/DefaultSubscriptionInternalApi.java 25(+14 -11)
subscription/src/main/java/org/killbill/billing/subscription/api/timeline/DefaultSubscriptionBaseTimelineApi.java 12(+6 -6)
subscription/src/main/java/org/killbill/billing/subscription/api/user/DefaultSubscriptionBaseApiService.java 18(+10 -8)
subscription/src/main/java/org/killbill/billing/subscription/engine/addon/AddonUtils.java 64(+6 -58)
subscription/src/main/java/org/killbill/billing/subscription/engine/dao/DefaultSubscriptionDao.java 74(+38 -36)
subscription/src/main/java/org/killbill/billing/subscription/engine/dao/model/SubscriptionModelDao.java 2(+1 -1)
subscription/src/main/java/org/killbill/billing/subscription/engine/dao/SubscriptionDao.java 4(+2 -2)
subscription/src/test/java/org/killbill/billing/subscription/api/user/TestUserApiAddOn.java 14(+8 -6)
subscription/src/test/java/org/killbill/billing/subscription/engine/dao/MockSubscriptionDaoMemory.java 31(+15 -16)
Details
diff --git a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestPublicBus.java b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestPublicBus.java
index e3d7799..2c9aa27 100644
--- a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestPublicBus.java
+++ b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestPublicBus.java
@@ -74,6 +74,10 @@ public class TestPublicBus extends TestIntegrationBase {
@Override
@BeforeMethod(groups = "slow")
public void beforeMethod() throws Exception {
+ if (hasFailed()) {
+ return;
+ }
+
/*
We copy the initialization instead of invoking the super method so we can add the registration
of the publicBus event;
@@ -107,6 +111,10 @@ public class TestPublicBus extends TestIntegrationBase {
@AfterMethod(groups = "slow")
public void afterMethod() throws Exception {
+ if (hasFailed()) {
+ return;
+ }
+
externalBus.unregister(publicListener);
super.afterMethod();
}
@@ -180,7 +188,7 @@ public class TestPublicBus extends TestIntegrationBase {
event.getEventType() == ExtBusEventType.SUBSCRIPTION_UNCANCEL ||
event.getEventType() == ExtBusEventType.SUBSCRIPTION_BCD_CHANGE) {
try {
- final SubscriptionMetadata obj = (SubscriptionMetadata) mapper.readValue(event.getMetaData(), SubscriptionMetadata.class);
+ final SubscriptionMetadata obj = mapper.readValue(event.getMetaData(), SubscriptionMetadata.class);
Assert.assertNotNull(obj.getBundleExternalKey());
Assert.assertNotNull(obj.getActionType());
} catch (final JsonParseException e) {
diff --git a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestWithInvoicePlugin.java b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestWithInvoicePlugin.java
index c6a2b73..db8c664 100644
--- a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestWithInvoicePlugin.java
+++ b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestWithInvoicePlugin.java
@@ -119,6 +119,10 @@ public class TestWithInvoicePlugin extends TestIntegrationBase {
@BeforeMethod(groups = "slow")
public void setUp() throws Exception {
+ if (hasFailed()) {
+ return;
+ }
+
testInvoicePluginApi.additionalInvoiceItem = null;
testInvoicePluginApi.shouldAddTaxItem = true;
testInvoicePluginApi.isAborted = false;
diff --git a/catalog/src/main/java/org/killbill/billing/catalog/VersionedCatalog.java b/catalog/src/main/java/org/killbill/billing/catalog/VersionedCatalog.java
index f970b68..6e171ad 100644
--- a/catalog/src/main/java/org/killbill/billing/catalog/VersionedCatalog.java
+++ b/catalog/src/main/java/org/killbill/billing/catalog/VersionedCatalog.java
@@ -1,7 +1,7 @@
/*
* Copyright 2010-2013 Ning, Inc.
- * Copyright 2014-2017 Groupon, Inc
- * Copyright 2014-2017 The Billing Project, LLC
+ * Copyright 2014-2018 Groupon, Inc
+ * Copyright 2014-2018 The Billing Project, LLC
*
* The Billing Project 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
@@ -310,36 +310,53 @@ public class VersionedCatalog extends ValidatingConfig<VersionedCatalog> impleme
return entry.getStaticCatalog().findCurrentPricelist(entry.getPlan().getPriceListName());
}
- public PriceList findPriceList(final String name, final DateTime requestedDate)
- throws CatalogApiException {
- return versionForDate(requestedDate).findCurrentPriceList(name);
- }
-
@Override
- public BillingActionPolicy planCancelPolicy(final PlanPhaseSpecifier planPhase, final DateTime requestedDate) throws CatalogApiException {
- return versionForDate(requestedDate).planCancelPolicy(planPhase);
+ public BillingActionPolicy planCancelPolicy(final PlanPhaseSpecifier planPhase,
+ final DateTime requestedDate,
+ final DateTime subscriptionStartDate) throws CatalogApiException {
+ final StaticCatalog staticCatalog = getStaticCatalog(planPhase, requestedDate, subscriptionStartDate);
+ return staticCatalog.planCancelPolicy(planPhase);
}
@Override
public PlanAlignmentChange planChangeAlignment(final PlanPhaseSpecifier from,
- final PlanSpecifier to, final DateTime requestedDate) throws CatalogApiException {
- return versionForDate(requestedDate).planChangeAlignment(from, to);
+ final PlanSpecifier to,
+ final DateTime requestedDate,
+ final DateTime subscriptionStartDate) throws CatalogApiException {
+ final StaticCatalog staticCatalog = getStaticCatalog(from, requestedDate, subscriptionStartDate);
+ return staticCatalog.planChangeAlignment(from, to);
}
@Override
- public PlanAlignmentCreate planCreateAlignment(final PlanSpecifier specifier, final DateTime requestedDate) throws CatalogApiException {
- return versionForDate(requestedDate).planCreateAlignment(specifier);
+ public PlanAlignmentCreate planCreateAlignment(final PlanSpecifier specifier,
+ final DateTime requestedDate,
+ final DateTime subscriptionStartDate) throws CatalogApiException {
+ final StaticCatalog staticCatalog = getStaticCatalog(specifier, requestedDate, subscriptionStartDate);
+ return staticCatalog.planCreateAlignment(specifier);
}
@Override
- public BillingAlignment billingAlignment(final PlanPhaseSpecifier planPhase, final DateTime requestedDate) throws CatalogApiException {
- return versionForDate(requestedDate).billingAlignment(planPhase);
+ public BillingAlignment billingAlignment(final PlanPhaseSpecifier planPhase,
+ final DateTime requestedDate,
+ final DateTime subscriptionStartDate) throws CatalogApiException {
+ final StaticCatalog staticCatalog = getStaticCatalog(planPhase, requestedDate, subscriptionStartDate);
+ return staticCatalog.billingAlignment(planPhase);
}
@Override
- public PlanChangeResult planChange(final PlanPhaseSpecifier from, final PlanSpecifier to, final DateTime requestedDate)
+ public PlanChangeResult planChange(final PlanPhaseSpecifier from,
+ final PlanSpecifier to,
+ final DateTime requestedDate,
+ final DateTime subscriptionStartDate)
throws CatalogApiException {
- return versionForDate(requestedDate).planChange(from, to);
+ final StaticCatalog staticCatalog = getStaticCatalog(from, requestedDate, subscriptionStartDate);
+ return staticCatalog.planChange(from, to);
+ }
+
+ // Note that the PlanSpecifier billing period must refer here to the recurring phase one when a plan name isn't specified
+ private StaticCatalog getStaticCatalog(final PlanSpecifier spec, final DateTime requestedDate, final DateTime subscriptionStartDate) throws CatalogApiException {
+ final CatalogPlanEntry entry = findCatalogPlanEntry(new PlanRequestWrapper(spec), requestedDate, subscriptionStartDate);
+ return entry.getStaticCatalog();
}
@Override
@@ -507,8 +524,11 @@ public class VersionedCatalog extends ValidatingConfig<VersionedCatalog> impleme
private final PlanPhasePriceOverridesWithCallContext overrides;
public PlanRequestWrapper(final String planName) {
- this.spec = new PlanSpecifier(planName);
- this.overrides = null;
+ this(new PlanSpecifier(planName));
+ }
+
+ public PlanRequestWrapper(final PlanSpecifier spec) {
+ this(spec, null);
}
public PlanRequestWrapper(final PlanSpecifier spec,
diff --git a/catalog/src/test/java/org/killbill/billing/catalog/MockCatalog.java b/catalog/src/test/java/org/killbill/billing/catalog/MockCatalog.java
index 9720f64..5b3f1b2 100644
--- a/catalog/src/test/java/org/killbill/billing/catalog/MockCatalog.java
+++ b/catalog/src/test/java/org/killbill/billing/catalog/MockCatalog.java
@@ -147,28 +147,28 @@ public class MockCatalog extends StandaloneCatalog implements Catalog {
}
@Override
- public PlanChangeResult planChange(final PlanPhaseSpecifier from, final PlanSpecifier to, final DateTime requestedDate) {
+ public PlanChangeResult planChange(final PlanPhaseSpecifier from, final PlanSpecifier to, final DateTime requestedDate, final DateTime subscriptionStartDate) {
return planChange(from, to);
}
@Override
- public BillingActionPolicy planCancelPolicy(final PlanPhaseSpecifier planPhase, final DateTime requestedDate)
+ public BillingActionPolicy planCancelPolicy(final PlanPhaseSpecifier planPhase, final DateTime requestedDate, final DateTime subscriptionStartDate)
throws CatalogApiException {
return planCancelPolicy(planPhase);
}
@Override
- public PlanAlignmentCreate planCreateAlignment(final PlanSpecifier specifier, final DateTime requestedDate) {
+ public PlanAlignmentCreate planCreateAlignment(final PlanSpecifier specifier, final DateTime requestedDate, final DateTime subscriptionStartDate) {
return planCreateAlignment(specifier);
}
@Override
- public BillingAlignment billingAlignment(final PlanPhaseSpecifier planPhase, final DateTime requestedDate) {
+ public BillingAlignment billingAlignment(final PlanPhaseSpecifier planPhase, final DateTime requestedDate, final DateTime subscriptionStartDate) {
return billingAlignment(planPhase);
}
@Override
- public PlanAlignmentChange planChangeAlignment(final PlanPhaseSpecifier from, final PlanSpecifier to, final DateTime requestedDate)
+ public PlanAlignmentChange planChangeAlignment(final PlanPhaseSpecifier from, final PlanSpecifier to, final DateTime requestedDate, final DateTime subscriptionStartDate)
throws CatalogApiException {
return planChangeAlignment(from, to);
}
diff --git a/entitlement/src/main/java/org/killbill/billing/entitlement/engine/core/EventsStreamBuilder.java b/entitlement/src/main/java/org/killbill/billing/entitlement/engine/core/EventsStreamBuilder.java
index 637ad39..6b1991b 100644
--- a/entitlement/src/main/java/org/killbill/billing/entitlement/engine/core/EventsStreamBuilder.java
+++ b/entitlement/src/main/java/org/killbill/billing/entitlement/engine/core/EventsStreamBuilder.java
@@ -36,14 +36,11 @@ import org.killbill.billing.account.api.AccountApiException;
import org.killbill.billing.account.api.AccountInternalApi;
import org.killbill.billing.account.api.ImmutableAccountData;
import org.killbill.billing.callcontext.InternalTenantContext;
-import org.killbill.billing.catalog.api.BillingPeriod;
import org.killbill.billing.catalog.api.Catalog;
import org.killbill.billing.catalog.api.CatalogApiException;
import org.killbill.billing.catalog.api.CatalogInternalApi;
import org.killbill.billing.catalog.api.PhaseType;
-import org.killbill.billing.catalog.api.PlanPhase;
import org.killbill.billing.catalog.api.PlanPhaseSpecifier;
-import org.killbill.billing.catalog.api.Product;
import org.killbill.billing.catalog.api.ProductCategory;
import org.killbill.billing.entitlement.AccountEventsStreams;
import org.killbill.billing.entitlement.EventsStream;
@@ -423,36 +420,17 @@ public class EventsStreamBuilder {
}
private PlanPhaseSpecifier createPlanPhaseSpecifier(final SubscriptionBase subscription) {
-
- final String lastActiveProductName;
- final BillingPeriod billingPeriod;
- final ProductCategory productCategory;
- final String priceListName;
+ final String planName;
final PhaseType phaseType;
-
if (subscription.getState() == EntitlementState.PENDING) {
final SubscriptionBaseTransition transition = subscription.getPendingTransition();
- final Product pendingProduct = transition.getNextPlan().getProduct();
- lastActiveProductName = pendingProduct.getName();
- productCategory = pendingProduct.getCategory();
- final PlanPhase pendingPlanPhase = transition.getNextPhase();
- billingPeriod = pendingPlanPhase.getRecurring() != null ? pendingPlanPhase.getRecurring().getBillingPeriod() : BillingPeriod.NO_BILLING_PERIOD;
- priceListName = transition.getNextPriceList().getName();
+ planName = transition.getNextPlan().getName();
phaseType = transition.getNextPhase().getPhaseType();
} else {
- final Product lastActiveProduct = subscription.getLastActiveProduct();
- lastActiveProductName = lastActiveProduct.getName();
- productCategory = lastActiveProduct.getCategory();
- final PlanPhase lastActivePlanPhase = subscription.getLastActivePhase();
- billingPeriod = lastActivePlanPhase.getRecurring() != null ? lastActivePlanPhase.getRecurring().getBillingPeriod() : BillingPeriod.NO_BILLING_PERIOD;
- priceListName = subscription.getLastActivePlan().getPriceListName();
+ planName = subscription.getLastActivePlan().getName();
phaseType = subscription.getLastActivePhase().getPhaseType();
}
- return new PlanPhaseSpecifier(lastActiveProductName,
- billingPeriod,
- priceListName,
- phaseType);
-
+ return new PlanPhaseSpecifier(planName, phaseType);
}
private Catalog getCatalog(final InternalTenantContext internalTenantContext) throws EntitlementApiException {
diff --git a/entitlement/src/test/java/org/killbill/billing/entitlement/block/TestBlockingChecker.java b/entitlement/src/test/java/org/killbill/billing/entitlement/block/TestBlockingChecker.java
index e8ac66b..193f506 100644
--- a/entitlement/src/test/java/org/killbill/billing/entitlement/block/TestBlockingChecker.java
+++ b/entitlement/src/test/java/org/killbill/billing/entitlement/block/TestBlockingChecker.java
@@ -47,6 +47,10 @@ public class TestBlockingChecker extends EntitlementTestSuiteNoDB {
@BeforeMethod(groups = "fast")
public void beforeMethod() throws Exception {
+ if (hasFailed()) {
+ return;
+ }
+
super.beforeMethod();
final UUID accountId = UUID.randomUUID();
account = Mockito.mock(Account.class);
diff --git a/entitlement/src/test/java/org/killbill/billing/entitlement/engine/core/TestEntitlementUtils.java b/entitlement/src/test/java/org/killbill/billing/entitlement/engine/core/TestEntitlementUtils.java
index c2b31fd..43974f9 100644
--- a/entitlement/src/test/java/org/killbill/billing/entitlement/engine/core/TestEntitlementUtils.java
+++ b/entitlement/src/test/java/org/killbill/billing/entitlement/engine/core/TestEntitlementUtils.java
@@ -65,6 +65,9 @@ public class TestEntitlementUtils extends EntitlementTestSuiteWithEmbeddedDB {
@BeforeMethod(groups = "slow")
public void setUp() throws Exception {
+ if (hasFailed()) {
+ return;
+ }
clock.setDay(initialDate);
final Account account = createAccount(getAccountData(7));
diff --git a/junction/src/main/java/org/killbill/billing/junction/plumbing/billing/DefaultInternalBillingApi.java b/junction/src/main/java/org/killbill/billing/junction/plumbing/billing/DefaultInternalBillingApi.java
index 154f9e0..73dc2cb 100644
--- a/junction/src/main/java/org/killbill/billing/junction/plumbing/billing/DefaultInternalBillingApi.java
+++ b/junction/src/main/java/org/killbill/billing/junction/plumbing/billing/DefaultInternalBillingApi.java
@@ -235,7 +235,7 @@ public class DefaultInternalBillingApi implements BillingInternalApi {
private int calculateBcdForTransition(final Catalog catalog, final Map<UUID, Integer> bcdCache, final SubscriptionBase baseSubscription, final SubscriptionBase subscription, final int accountBillCycleDayLocal, final EffectiveSubscriptionInternalEvent transition, final InternalTenantContext internalTenantContext)
throws CatalogApiException, AccountApiException, SubscriptionBaseApiException {
- final BillingAlignment alignment = catalog.billingAlignment(getPlanPhaseSpecifierFromTransition(catalog, transition), subscription.getStartDate());
+ final BillingAlignment alignment = catalog.billingAlignment(getPlanPhaseSpecifierFromTransition(catalog, transition), transition.getEffectiveTransitionTime(), subscription.getStartDate());
return BillCycleDayCalculator.calculateBcdForAlignment(bcdCache, subscription, baseSubscription, alignment, internalTenantContext, accountBillCycleDayLocal);
}
diff --git a/junction/src/test/java/org/killbill/billing/junction/plumbing/billing/TestBillingApi.java b/junction/src/test/java/org/killbill/billing/junction/plumbing/billing/TestBillingApi.java
index fc918d0..4f7e151 100644
--- a/junction/src/test/java/org/killbill/billing/junction/plumbing/billing/TestBillingApi.java
+++ b/junction/src/test/java/org/killbill/billing/junction/plumbing/billing/TestBillingApi.java
@@ -1,7 +1,7 @@
/*
* Copyright 2010-2013 Ning, Inc.
- * Copyright 2014-2016 Groupon, Inc
- * Copyright 2014-2016 The Billing Project, LLC
+ * Copyright 2014-2018 Groupon, Inc
+ * Copyright 2014-2018 The Billing Project, LLC
*
* The Billing Project 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
pom.xml 2(+1 -1)
diff --git a/pom.xml b/pom.xml
index cdf7211..abc03d6 100644
--- a/pom.xml
+++ b/pom.xml
@@ -21,7 +21,7 @@
<parent>
<artifactId>killbill-oss-parent</artifactId>
<groupId>org.kill-bill.billing</groupId>
- <version>0.141.68-SNAPSHOT</version>
+ <version>0.141.68</version>
</parent>
<artifactId>killbill</artifactId>
<version>0.19.16-SNAPSHOT</version>
diff --git a/subscription/src/main/java/org/killbill/billing/subscription/alignment/PlanAligner.java b/subscription/src/main/java/org/killbill/billing/subscription/alignment/PlanAligner.java
index 278ea3c..35bd5e1 100644
--- a/subscription/src/main/java/org/killbill/billing/subscription/alignment/PlanAligner.java
+++ b/subscription/src/main/java/org/killbill/billing/subscription/alignment/PlanAligner.java
@@ -208,7 +208,7 @@ public class PlanAligner extends BaseAligner {
final PlanSpecifier planSpecifier = new PlanSpecifier(plan.getName());
final DateTime planStartDate;
- final PlanAlignmentCreate alignment = catalog.planCreateAlignment(planSpecifier, catalogEffectiveDate);
+ final PlanAlignmentCreate alignment = catalog.planCreateAlignment(planSpecifier, catalogEffectiveDate, subscriptionStartDate);
switch (alignment) {
case START_OF_SUBSCRIPTION:
planStartDate = subscriptionStartDate;
@@ -271,7 +271,7 @@ public class PlanAligner extends BaseAligner {
final PlanSpecifier toPlanSpecifier = new PlanSpecifier(nextPlan.getName());
final PhaseType initialPhase;
final DateTime planStartDate;
- final PlanAlignmentChange alignment = catalog.planChangeAlignment(fromPlanPhaseSpecifier, toPlanSpecifier, catalogEffectiveDate);
+ final PlanAlignmentChange alignment = catalog.planChangeAlignment(fromPlanPhaseSpecifier, toPlanSpecifier, catalogEffectiveDate, subscriptionStartDate);
switch (alignment) {
case START_OF_SUBSCRIPTION:
planStartDate = subscriptionStartDate;
diff --git a/subscription/src/main/java/org/killbill/billing/subscription/api/SubscriptionApiBase.java b/subscription/src/main/java/org/killbill/billing/subscription/api/SubscriptionApiBase.java
index 478f24f..79774ef 100644
--- a/subscription/src/main/java/org/killbill/billing/subscription/api/SubscriptionApiBase.java
+++ b/subscription/src/main/java/org/killbill/billing/subscription/api/SubscriptionApiBase.java
@@ -75,8 +75,7 @@ public class SubscriptionApiBase {
protected SubscriptionBaseBundle getActiveBundleForKey(final String bundleKey, final Catalog catalog, final InternalTenantContext context) throws CatalogApiException {
final List<SubscriptionBaseBundle> existingBundles = dao.getSubscriptionBundlesForKey(bundleKey, context);
for (final SubscriptionBaseBundle cur : existingBundles) {
- final List<SubscriptionBase> subscriptions;
- subscriptions = dao.getSubscriptions(cur.getId(), ImmutableList.<SubscriptionBaseEvent>of(), catalog, context);
+ final List<DefaultSubscriptionBase> subscriptions = dao.getSubscriptions(cur.getId(), ImmutableList.<SubscriptionBaseEvent>of(), catalog, context);
for (final SubscriptionBase s : subscriptions) {
if (s.getCategory() == ProductCategory.ADD_ON) {
continue;
@@ -99,19 +98,18 @@ public class SubscriptionApiBase {
return createSubscriptionForApiUse(result);
}
- protected List<SubscriptionBase> getSubscriptionsForBundle(final UUID bundleId,
- @Nullable final DryRunArguments dryRunArguments,
- final Catalog catalog,
- final AddonUtils addonUtils,
- final TenantContext tenantContext,
- final InternalTenantContext context) throws SubscriptionBaseApiException, CatalogApiException {
+ protected List<DefaultSubscriptionBase> getSubscriptionsForBundle(final UUID bundleId,
+ @Nullable final DryRunArguments dryRunArguments,
+ final Catalog catalog,
+ final AddonUtils addonUtils,
+ final TenantContext tenantContext,
+ final InternalTenantContext context) throws SubscriptionBaseApiException, CatalogApiException {
final List<SubscriptionBaseEvent> outputDryRunEvents = new ArrayList<SubscriptionBaseEvent>();
- final List<SubscriptionBase> outputSubscriptions = new ArrayList<SubscriptionBase>();
+ final List<DefaultSubscriptionBase> outputSubscriptions = new ArrayList<DefaultSubscriptionBase>();
populateDryRunEvents(bundleId, dryRunArguments, outputDryRunEvents, outputSubscriptions, catalog, addonUtils, tenantContext, context);
- final List<SubscriptionBase> result;
- result = dao.getSubscriptions(bundleId, outputDryRunEvents, catalog, context);
+ final List<DefaultSubscriptionBase> result = dao.getSubscriptions(bundleId, outputDryRunEvents, catalog, context);
if (result != null && !result.isEmpty()) {
outputSubscriptions.addAll(result);
}
@@ -123,7 +121,7 @@ public class SubscriptionApiBase {
private void populateDryRunEvents(@Nullable final UUID bundleId,
@Nullable final DryRunArguments dryRunArguments,
final Collection<SubscriptionBaseEvent> outputDryRunEvents,
- final Collection<SubscriptionBase> outputSubscriptions,
+ final Collection<DefaultSubscriptionBase> outputSubscriptions,
final Catalog catalog,
final AddonUtils addonUtils,
final TenantContext tenantContext,
@@ -138,7 +136,7 @@ public class SubscriptionApiBase {
final boolean isInputSpecNullOrEmpty = inputSpec == null ||
(inputSpec.getPlanName() == null && inputSpec.getProductName() == null && inputSpec.getBillingPeriod() == null);
- // Create an overridesWithContext with a null context to indicate this is dryRun and no price overriden plan should be created.
+ // Create an overridesWithContext with a null context to indicate this is dryRun and no price overridden plan should be created.
final PlanPhasePriceOverridesWithCallContext overridesWithContext = new DefaultPlanPhasePriceOverridesWithCallContext(dryRunArguments.getPlanPhasePriceOverrides(), null);
final Plan plan = isInputSpecNullOrEmpty ?
null :
@@ -148,7 +146,7 @@ public class SubscriptionApiBase {
case START_BILLING:
final SubscriptionBase baseSubscription = dao.getBaseSubscription(bundleId, catalog, context);
final DateTime startEffectiveDate = dryRunArguments.getEffectiveDate() != null ? context.toUTCDateTime(dryRunArguments.getEffectiveDate()) : utcNow;
- final DateTime bundleStartDate = getBundleStartDateWithSanity(bundleId, baseSubscription, plan, startEffectiveDate, catalog, addonUtils, context);
+ final DateTime bundleStartDate = getBundleStartDateWithSanity(bundleId, baseSubscription, plan, startEffectiveDate, addonUtils, context);
final UUID subscriptionId = UUIDs.randomUUID();
dryRunEvents = apiService.getEventsOnCreation(subscriptionId, startEffectiveDate, bundleStartDate, plan, inputSpec.getPhaseType(), plan.getPriceListName(),
startEffectiveDate, catalog, context);
@@ -190,7 +188,7 @@ public class SubscriptionApiBase {
final Plan currentPlan = subscriptionForCancellation.getCurrentPlan();
final PlanPhaseSpecifier spec = new PlanPhaseSpecifier(currentPlan.getName(),
subscriptionForCancellation.getCurrentPhase().getPhaseType());
- policy = catalog.planCancelPolicy(spec, subscriptionForCancellation.getStartDate());
+ policy = catalog.planCancelPolicy(spec, clock.getUTCNow(), subscriptionForCancellation.getStartDate());
}
// We pass null for billingAlignment, accountTimezone, account BCD because this is not available which means that dryRun with START_OF_TERM BillingPolicy will fail
cancelEffectiveDate = subscriptionForCancellation.getPlanChangeEffectiveDate(policy, null, -1, context);
@@ -226,7 +224,6 @@ public class SubscriptionApiBase {
@Nullable final SubscriptionBase baseSubscription,
final Plan plan,
final DateTime effectiveDate,
- final Catalog catalog,
final AddonUtils addonUtils,
final InternalTenantContext context) throws SubscriptionBaseApiException, CatalogApiException {
switch (plan.getProduct().getCategory()) {
@@ -244,7 +241,7 @@ public class SubscriptionApiBase {
if (effectiveDate.isBefore(baseSubscription.getStartDate())) {
throw new SubscriptionBaseApiException(ErrorCode.SUB_INVALID_REQUESTED_DATE, effectiveDate.toString(), baseSubscription.getStartDate().toString());
}
- addonUtils.checkAddonCreationRights(baseSubscription, plan, effectiveDate, catalog, context);
+ addonUtils.checkAddonCreationRights(baseSubscription, plan, effectiveDate, context);
return baseSubscription.getStartDate();
case STANDALONE:
@@ -278,10 +275,10 @@ public class SubscriptionApiBase {
return subscriptionBundle;
}
- protected List<SubscriptionBase> createSubscriptionsForApiUse(final Collection<SubscriptionBase> internalSubscriptions) {
- return new ArrayList<SubscriptionBase>(Collections2.transform(internalSubscriptions, new Function<SubscriptionBase, SubscriptionBase>() {
+ protected List<DefaultSubscriptionBase> createSubscriptionsForApiUse(final Collection<DefaultSubscriptionBase> internalSubscriptions) {
+ return new ArrayList<DefaultSubscriptionBase>(Collections2.transform(internalSubscriptions, new Function<SubscriptionBase, DefaultSubscriptionBase>() {
@Override
- public SubscriptionBase apply(final SubscriptionBase subscription) {
+ public DefaultSubscriptionBase apply(final SubscriptionBase subscription) {
return createSubscriptionForApiUse(subscription);
}
}));
diff --git a/subscription/src/main/java/org/killbill/billing/subscription/api/svcs/DefaultSubscriptionBaseCreateApi.java b/subscription/src/main/java/org/killbill/billing/subscription/api/svcs/DefaultSubscriptionBaseCreateApi.java
index 5825a95..61c5429 100644
--- a/subscription/src/main/java/org/killbill/billing/subscription/api/svcs/DefaultSubscriptionBaseCreateApi.java
+++ b/subscription/src/main/java/org/killbill/billing/subscription/api/svcs/DefaultSubscriptionBaseCreateApi.java
@@ -40,6 +40,7 @@ import org.killbill.billing.subscription.api.SubscriptionBase;
import org.killbill.billing.subscription.api.SubscriptionBaseApiService;
import org.killbill.billing.subscription.api.SubscriptionBaseWithAddOns;
import org.killbill.billing.subscription.api.SubscriptionBaseWithAddOnsSpecifier;
+import org.killbill.billing.subscription.api.user.DefaultSubscriptionBase;
import org.killbill.billing.subscription.api.user.SubscriptionAndAddOnsSpecifier;
import org.killbill.billing.subscription.api.user.SubscriptionBaseApiException;
import org.killbill.billing.subscription.api.user.SubscriptionBaseBundle;
@@ -230,7 +231,7 @@ public class DefaultSubscriptionBaseCreateApi extends SubscriptionApiBase {
if (ProductCategory.ADD_ON.toString().equalsIgnoreCase(plan.getProduct().getCategory().toString())) {
if (plan.getPlansAllowedInBundle() != -1 && plan.getPlansAllowedInBundle() > 0) {
// TODO We should also look to the specifiers being created for validation
- final List<SubscriptionBase> subscriptionsForBundle = getSubscriptionsForBundle(bundle.getId(), null, catalog, addonUtils, callContext, context);
+ final List<DefaultSubscriptionBase> subscriptionsForBundle = getSubscriptionsForBundle(bundle.getId(), null, catalog, addonUtils, callContext, context);
final int existingAddOnsWithSamePlanName = addonUtils.countExistingAddOnsWithSamePlanName(subscriptionsForBundle, plan.getName());
final int currentAddOnsWithSamePlanName = countCurrentAddOnsWithSamePlanName(entitlementsPlans, plan);
if ((existingAddOnsWithSamePlanName + currentAddOnsWithSamePlanName) > plan.getPlansAllowedInBundle()) {
@@ -245,7 +246,7 @@ public class DefaultSubscriptionBaseCreateApi extends SubscriptionApiBase {
bundleStartDate = effectiveDate;
} else {
final SubscriptionBase baseSubscription = dao.getBaseSubscription(bundle.getId(), catalog, context);
- bundleStartDate = getBundleStartDateWithSanity(bundle.getId(), baseSubscription, plan, effectiveDate, catalog, addonUtils, context);
+ bundleStartDate = getBundleStartDateWithSanity(bundle.getId(), baseSubscription, plan, effectiveDate, addonUtils, context);
}
final SubscriptionSpecifier subscription = new SubscriptionSpecifier();
diff --git a/subscription/src/main/java/org/killbill/billing/subscription/api/svcs/DefaultSubscriptionInternalApi.java b/subscription/src/main/java/org/killbill/billing/subscription/api/svcs/DefaultSubscriptionInternalApi.java
index d1272e8..dfdb63e 100644
--- a/subscription/src/main/java/org/killbill/billing/subscription/api/svcs/DefaultSubscriptionInternalApi.java
+++ b/subscription/src/main/java/org/killbill/billing/subscription/api/svcs/DefaultSubscriptionInternalApi.java
@@ -18,6 +18,7 @@
package org.killbill.billing.subscription.api.svcs;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.HashMap;
@@ -39,10 +40,10 @@ import org.killbill.billing.catalog.api.Catalog;
import org.killbill.billing.catalog.api.CatalogApiException;
import org.killbill.billing.catalog.api.CatalogInternalApi;
import org.killbill.billing.catalog.api.Plan;
-import org.killbill.billing.catalog.api.PlanChangeResult;
import org.killbill.billing.catalog.api.PlanPhasePriceOverride;
import org.killbill.billing.catalog.api.PlanPhasePriceOverridesWithCallContext;
import org.killbill.billing.catalog.api.PlanPhaseSpecifier;
+import org.killbill.billing.catalog.api.Product;
import org.killbill.billing.catalog.api.ProductCategory;
import org.killbill.billing.entitlement.api.Entitlement.EntitlementState;
import org.killbill.billing.entitlement.api.EntitlementAOStatusDryRun;
@@ -69,7 +70,6 @@ import org.killbill.billing.subscription.engine.dao.model.SubscriptionBundleMode
import org.killbill.billing.subscription.events.SubscriptionBaseEvent;
import org.killbill.billing.subscription.events.bcd.BCDEvent;
import org.killbill.billing.subscription.events.bcd.BCDEventData;
-import org.killbill.billing.util.UUIDs;
import org.killbill.billing.util.bcd.BillCycleDayCalculator;
import org.killbill.billing.util.cache.AccountIdFromBundleIdCacheLoader;
import org.killbill.billing.util.cache.BundleIdFromSubscriptionIdCacheLoader;
@@ -273,7 +273,8 @@ public class DefaultSubscriptionInternalApi extends DefaultSubscriptionBaseCreat
try {
final Catalog catalog = catalogInternalApi.getFullCatalog(true, true, context);
final TenantContext tenantContext = internalCallContextFactory.createTenantContext(context);
- return super.getSubscriptionsForBundle(bundleId, dryRunArguments, catalog, addonUtils, tenantContext, context);
+ final List<DefaultSubscriptionBase> subscriptionsForBundle = super.getSubscriptionsForBundle(bundleId, dryRunArguments, catalog, addonUtils, tenantContext, context);
+ return new ArrayList<SubscriptionBase>(subscriptionsForBundle);
} catch (final CatalogApiException e) {
throw new SubscriptionBaseApiException(e);
}
@@ -282,10 +283,11 @@ public class DefaultSubscriptionInternalApi extends DefaultSubscriptionBaseCreat
@Override
public Map<UUID, List<SubscriptionBase>> getSubscriptionsForAccount(final Catalog catalog, final InternalTenantContext context) throws SubscriptionBaseApiException {
try {
- final Map<UUID, List<SubscriptionBase>> internalSubscriptions = dao.getSubscriptionsForAccount(catalog, context);
+ final Map<UUID, List<DefaultSubscriptionBase>> internalSubscriptions = dao.getSubscriptionsForAccount(catalog, context);
final Map<UUID, List<SubscriptionBase>> result = new HashMap<UUID, List<SubscriptionBase>>();
for (final UUID bundleId : internalSubscriptions.keySet()) {
- result.put(bundleId, createSubscriptionsForApiUse(internalSubscriptions.get(bundleId)));
+ final List<DefaultSubscriptionBase> subscriptionsForApiUse = createSubscriptionsForApiUse(internalSubscriptions.get(bundleId));
+ result.put(bundleId, new ArrayList<SubscriptionBase>(subscriptionsForApiUse));
}
return result;
} catch (final CatalogApiException e) {
@@ -375,7 +377,7 @@ public class DefaultSubscriptionInternalApi extends DefaultSubscriptionBaseCreat
if (ProductCategory.ADD_ON.toString().equalsIgnoreCase(plan.getProduct().getCategory().toString())) {
if (plan.getPlansAllowedInBundle() != -1
&& plan.getPlansAllowedInBundle() > 0
- && addonUtils.countExistingAddOnsWithSamePlanName(getSubscriptionsForBundle(subscription.getBundleId(), null, context), plan.getName())
+ && addonUtils.countExistingAddOnsWithSamePlanName(getSubscriptionsForBundle(subscription.getBundleId(), null, catalog, addonUtils, callContext, context), plan.getName())
>= plan.getPlansAllowedInBundle()) {
// the plan can be changed to the new value, because it has reached its limit by bundle
throw new SubscriptionBaseApiException(ErrorCode.SUB_CHANGE_AO_MAX_PLAN_ALLOWED_BY_BUNDLE, plan.getName());
@@ -400,7 +402,7 @@ public class DefaultSubscriptionInternalApi extends DefaultSubscriptionBaseCreat
final List<EntitlementAOStatusDryRun> result = new LinkedList<EntitlementAOStatusDryRun>();
- final List<SubscriptionBase> bundleSubscriptions = dao.getSubscriptions(subscription.getBundleId(), ImmutableList.<SubscriptionBaseEvent>of(), catalog, context);
+ final List<DefaultSubscriptionBase> bundleSubscriptions = dao.getSubscriptions(subscription.getBundleId(), ImmutableList.<SubscriptionBaseEvent>of(), catalog, context);
for (final SubscriptionBase cur : bundleSubscriptions) {
if (cur.getId().equals(subscriptionId)) {
continue;
@@ -411,11 +413,13 @@ public class DefaultSubscriptionInternalApi extends DefaultSubscriptionBaseCreat
continue;
}
+ final Product baseProduct = baseProductName != null ? catalog.findProduct(baseProductName, requestedDate) : null;
+
final DryRunChangeReason reason;
// If baseProductName is null, it's a cancellation dry-run. In this case, return all addons, so they are cancelled
- if (baseProductName != null && addonUtils.isAddonIncludedFromProdName(baseProductName, cur.getCurrentPlan(), requestedDate, catalog, context)) {
+ if (baseProduct != null && addonUtils.isAddonIncluded(baseProduct, cur.getCurrentPlan())) {
reason = DryRunChangeReason.AO_INCLUDED_IN_NEW_PLAN;
- } else if (baseProductName != null && addonUtils.isAddonAvailableFromProdName(baseProductName, cur.getCurrentPlan(), requestedDate, catalog, context)) {
+ } else if (baseProduct != null && addonUtils.isAddonAvailable(baseProduct, cur.getCurrentPlan())) {
reason = DryRunChangeReason.AO_AVAILABLE_IN_NEW_PLAN;
} else {
reason = DryRunChangeReason.AO_NOT_AVAILABLE_IN_NEW_PLAN;
@@ -431,7 +435,6 @@ public class DefaultSubscriptionInternalApi extends DefaultSubscriptionBaseCreat
} catch (final CatalogApiException e) {
throw new SubscriptionBaseApiException(e);
}
-
}
@Override
@@ -457,7 +460,7 @@ public class DefaultSubscriptionInternalApi extends DefaultSubscriptionBaseCreat
@Override
public int getDefaultBillCycleDayLocal(final Map<UUID, Integer> bcdCache, final SubscriptionBase subscription, final SubscriptionBase baseSubscription, final PlanPhaseSpecifier planPhaseSpecifier, final int accountBillCycleDayLocal, final Catalog catalog, final InternalTenantContext context) throws SubscriptionBaseApiException {
try {
- final BillingAlignment alignment = catalog.billingAlignment(planPhaseSpecifier, subscription.getStartDate());
+ final BillingAlignment alignment = catalog.billingAlignment(planPhaseSpecifier, clock.getUTCNow(), subscription.getStartDate());
return BillCycleDayCalculator.calculateBcdForAlignment(bcdCache, subscription, baseSubscription, alignment, context, accountBillCycleDayLocal);
} catch (final CatalogApiException e) {
throw new SubscriptionBaseApiException(e);
diff --git a/subscription/src/main/java/org/killbill/billing/subscription/api/timeline/DefaultSubscriptionBaseTimelineApi.java b/subscription/src/main/java/org/killbill/billing/subscription/api/timeline/DefaultSubscriptionBaseTimelineApi.java
index 2ee1a66..b75e77f 100644
--- a/subscription/src/main/java/org/killbill/billing/subscription/api/timeline/DefaultSubscriptionBaseTimelineApi.java
+++ b/subscription/src/main/java/org/killbill/billing/subscription/api/timeline/DefaultSubscriptionBaseTimelineApi.java
@@ -68,10 +68,10 @@ public class DefaultSubscriptionBaseTimelineApi extends SubscriptionApiBase impl
final InternalTenantContext internalTenantContext = internalCallContextFactory.createInternalTenantContext(bundle.getAccountId(), context);
final Catalog fullCatalog = catalogInternalApi.getFullCatalog(true, true, internalTenantContext);
- final List<SubscriptionBase> subscriptions = dao.getSubscriptions(bundle.getId(),
- ImmutableList.<SubscriptionBaseEvent>of(),
- fullCatalog,
- internalTenantContext);
+ final List<DefaultSubscriptionBase> subscriptions = dao.getSubscriptions(bundle.getId(),
+ ImmutableList.<SubscriptionBaseEvent>of(),
+ fullCatalog,
+ internalTenantContext);
if (subscriptions.size() == 0) {
throw new SubscriptionBaseRepairException(ErrorCode.SUB_NO_ACTIVE_SUBSCRIPTIONS, bundle.getId());
}
@@ -83,7 +83,7 @@ public class DefaultSubscriptionBaseTimelineApi extends SubscriptionApiBase impl
}
}
- private String getViewId(final DateTime lastUpdateBundleDate, final List<SubscriptionBase> subscriptions) {
+ private String getViewId(final DateTime lastUpdateBundleDate, final List<DefaultSubscriptionBase> subscriptions) {
final StringBuilder tmp = new StringBuilder();
long lastOrderedId = -1;
for (final SubscriptionBase cur : subscriptions) {
@@ -130,7 +130,7 @@ public class DefaultSubscriptionBaseTimelineApi extends SubscriptionApiBase impl
};
}
- private List<SubscriptionBaseTimeline> createGetSubscriptionRepairList(final List<SubscriptionBase> subscriptions, final List<SubscriptionBaseTimeline> inRepair, final Catalog fullCatalog, final InternalTenantContext tenantContext) throws CatalogApiException {
+ private List<SubscriptionBaseTimeline> createGetSubscriptionRepairList(final List<DefaultSubscriptionBase> subscriptions, final List<SubscriptionBaseTimeline> inRepair, final Catalog fullCatalog, final InternalTenantContext tenantContext) throws CatalogApiException {
final List<SubscriptionBaseTimeline> result = new LinkedList<SubscriptionBaseTimeline>();
final Set<UUID> repairIds = new TreeSet<UUID>();
diff --git a/subscription/src/main/java/org/killbill/billing/subscription/api/user/DefaultSubscriptionBaseApiService.java b/subscription/src/main/java/org/killbill/billing/subscription/api/user/DefaultSubscriptionBaseApiService.java
index 6f3b516..9273757 100644
--- a/subscription/src/main/java/org/killbill/billing/subscription/api/user/DefaultSubscriptionBaseApiService.java
+++ b/subscription/src/main/java/org/killbill/billing/subscription/api/user/DefaultSubscriptionBaseApiService.java
@@ -174,7 +174,7 @@ public class DefaultSubscriptionBaseApiService implements SubscriptionBaseApiSer
try {
final InternalCallContext internalCallContext = createCallContextFromBundleId(subscription.getBundleId(), context);
final Catalog fullCatalog = catalogInternalApi.getFullCatalog(true, true, internalCallContext);
- final BillingActionPolicy policy = fullCatalog.planCancelPolicy(planPhase, subscription.getStartDate());
+ final BillingActionPolicy policy = fullCatalog.planCancelPolicy(planPhase, clock.getUTCNow(), subscription.getStartDate());
Preconditions.checkState(policy != BillingActionPolicy.START_OF_TERM, "A default START_OF_TERM policy is not availaible");
@@ -227,7 +227,9 @@ public class DefaultSubscriptionBaseApiService implements SubscriptionBaseApiSer
try {
for (final DefaultSubscriptionBase subscription : subscriptions) {
- final BillingAlignment billingAlignment = (subscription.getState() == EntitlementState.PENDING ? null : catalog.billingAlignment(new PlanPhaseSpecifier(subscription.getLastActivePlan().getName(), subscription.getLastActivePhase().getPhaseType()), subscription.getStartDate()));
+ final BillingAlignment billingAlignment = (subscription.getState() == EntitlementState.PENDING ? null : catalog.billingAlignment(new PlanPhaseSpecifier(subscription.getLastActivePlan().getName(), subscription.getLastActivePhase().getPhaseType()),
+ clock.getUTCNow(),
+ subscription.getStartDate()));
final DateTime effectiveDate = subscription.getPlanChangeEffectiveDate(policy, billingAlignment, accountBillCycleDayLocal, context);
subscriptionsWithEffectiveDate.put(subscription, effectiveDate);
}
@@ -389,7 +391,7 @@ public class DefaultSubscriptionBaseApiService implements SubscriptionBaseApiSer
final PlanPhaseSpecifier fromPlanPhase = new PlanPhaseSpecifier(currentPlan.getName(),
subscription.getCurrentOrPendingPhase().getPhaseType());
- planChangeResult = catalogInternalApi.getFullCatalog(true, true, internalCallContext).planChange(fromPlanPhase, toPlanPhase, subscription.getStartDate());
+ planChangeResult = catalogInternalApi.getFullCatalog(true, true, internalCallContext).planChange(fromPlanPhase, toPlanPhase, effectiveDate, subscription.getStartDate());
} catch (final CatalogApiException e) {
throw new SubscriptionBaseApiException(e);
}
@@ -606,7 +608,7 @@ public class DefaultSubscriptionBaseApiService implements SubscriptionBaseApiSer
}
}
- private List<DefaultSubscriptionBase> computeAddOnsToCancel(final Collection<SubscriptionBaseEvent> cancelEvents, final CatalogEntity baseProduct, final UUID bundleId, final DateTime effectiveDate, final Catalog catalog, final InternalCallContext internalCallContext) throws CatalogApiException {
+ private List<DefaultSubscriptionBase> computeAddOnsToCancel(final Collection<SubscriptionBaseEvent> cancelEvents, final Product baseProduct, final UUID bundleId, final DateTime effectiveDate, final Catalog catalog, final InternalCallContext internalCallContext) throws CatalogApiException {
// If cancellation/change occur in the future, there is nothing to do
if (effectiveDate.compareTo(internalCallContext.getCreatedDate()) > 0) {
return ImmutableList.<DefaultSubscriptionBase>of();
@@ -615,12 +617,12 @@ public class DefaultSubscriptionBaseApiService implements SubscriptionBaseApiSer
}
}
- private List<DefaultSubscriptionBase> addCancellationAddOnForEventsIfRequired(final Collection<SubscriptionBaseEvent> events, final CatalogEntity baseProduct, final UUID bundleId,
+ private List<DefaultSubscriptionBase> addCancellationAddOnForEventsIfRequired(final Collection<SubscriptionBaseEvent> events, final Product baseProduct, final UUID bundleId,
final DateTime effectiveDate, final Catalog catalog, final InternalTenantContext internalTenantContext) throws CatalogApiException {
final List<DefaultSubscriptionBase> subscriptionsToBeCancelled = new ArrayList<DefaultSubscriptionBase>();
- final List<SubscriptionBase> subscriptions = dao.getSubscriptions(bundleId, ImmutableList.<SubscriptionBaseEvent>of(), catalog, internalTenantContext);
+ final List<DefaultSubscriptionBase> subscriptions = dao.getSubscriptions(bundleId, ImmutableList.<SubscriptionBaseEvent>of(), catalog, internalTenantContext);
for (final SubscriptionBase subscription : subscriptions) {
final DefaultSubscriptionBase cur = (DefaultSubscriptionBase) subscription;
@@ -631,8 +633,8 @@ public class DefaultSubscriptionBaseApiService implements SubscriptionBaseApiSer
final Plan addonCurrentPlan = cur.getCurrentPlan();
if (baseProduct == null ||
- addonUtils.isAddonIncludedFromProdName(baseProduct.getName(), addonCurrentPlan, effectiveDate, catalog, internalTenantContext) ||
- !addonUtils.isAddonAvailableFromProdName(baseProduct.getName(), addonCurrentPlan, effectiveDate, catalog, internalTenantContext)) {
+ addonUtils.isAddonIncluded(baseProduct, addonCurrentPlan) ||
+ !addonUtils.isAddonAvailable(baseProduct, addonCurrentPlan)) {
//
// Perform AO cancellation using the effectiveDate of the BP
//
diff --git a/subscription/src/main/java/org/killbill/billing/subscription/engine/addon/AddonUtils.java b/subscription/src/main/java/org/killbill/billing/subscription/engine/addon/AddonUtils.java
index 587e1b7..da8dd4c 100644
--- a/subscription/src/main/java/org/killbill/billing/subscription/engine/addon/AddonUtils.java
+++ b/subscription/src/main/java/org/killbill/billing/subscription/engine/addon/AddonUtils.java
@@ -19,14 +19,10 @@
package org.killbill.billing.subscription.engine.addon;
import java.util.Collection;
-import java.util.List;
import org.joda.time.DateTime;
import org.killbill.billing.ErrorCode;
import org.killbill.billing.callcontext.InternalTenantContext;
-import org.killbill.billing.catalog.api.Catalog;
-import org.killbill.billing.catalog.api.CatalogApiException;
-import org.killbill.billing.catalog.api.CatalogInternalApi;
import org.killbill.billing.catalog.api.Plan;
import org.killbill.billing.catalog.api.Product;
import org.killbill.billing.catalog.api.ProductCategory;
@@ -34,27 +30,18 @@ import org.killbill.billing.entitlement.api.Entitlement.EntitlementState;
import org.killbill.billing.subscription.api.SubscriptionBase;
import org.killbill.billing.subscription.api.user.DefaultSubscriptionBase;
import org.killbill.billing.subscription.api.user.SubscriptionBaseApiException;
-import org.killbill.billing.subscription.exceptions.SubscriptionBaseError;
-
-import com.google.inject.Inject;
public class AddonUtils {
-
- @Inject
- public AddonUtils() {
- }
-
- public void checkAddonCreationRights(final SubscriptionBase baseSubscription, final Plan targetAddOnPlan, final DateTime requestedDate, final Catalog catalog, final InternalTenantContext context)
- throws SubscriptionBaseApiException, CatalogApiException {
-
+ public void checkAddonCreationRights(final SubscriptionBase baseSubscription, final Plan targetAddOnPlan, final DateTime requestedDate, final InternalTenantContext context)
+ throws SubscriptionBaseApiException {
if (baseSubscription.getState() == EntitlementState.CANCELLED ||
(baseSubscription.getState() == EntitlementState.PENDING && context.toLocalDate(baseSubscription.getStartDate()).compareTo(context.toLocalDate(requestedDate)) < 0)) {
throw new SubscriptionBaseApiException(ErrorCode.SUB_CREATE_AO_BP_NON_ACTIVE, targetAddOnPlan.getName());
}
final Plan currentOrPendingPlan = baseSubscription.getCurrentOrPendingPlan();
- final Product baseProduct = catalog.findProduct(currentOrPendingPlan.getProduct().getName(), requestedDate);
+ final Product baseProduct = currentOrPendingPlan.getProduct();
if (isAddonIncluded(baseProduct, targetAddOnPlan)) {
throw new SubscriptionBaseApiException(ErrorCode.SUB_CREATE_AO_ALREADY_INCLUDED,
targetAddOnPlan.getName(), currentOrPendingPlan.getProduct().getName());
@@ -66,46 +53,7 @@ public class AddonUtils {
}
}
- public boolean isAddonAvailableFromProdName(final String baseProductName, final Plan targetAddOnPlan, final DateTime requestedDate, final Catalog catalog, final InternalTenantContext context) {
- try {
- final Product product = catalog.findProduct(baseProductName, requestedDate);
- return isAddonAvailable(product, targetAddOnPlan);
- } catch (CatalogApiException e) {
- throw new SubscriptionBaseError(e);
- }
- }
-
- public boolean isAddonAvailableFromPlanName(final String basePlanName, final Plan targetAddOnPlan, final DateTime requestedDate, final Catalog catalog, final InternalTenantContext context) {
- try {
- final Plan plan = catalog.findPlan(basePlanName, requestedDate);
- final Product product = plan.getProduct();
- return isAddonAvailable(product, targetAddOnPlan);
- } catch (CatalogApiException e) {
- throw new SubscriptionBaseError(e);
- }
- }
-
- public boolean isAddonIncludedFromProdName(final String baseProductName, final Plan targetAddOnPlan, final DateTime requestedDate, final Catalog catalog, final InternalTenantContext context) {
- try {
- final Product product = catalog.findProduct(baseProductName, requestedDate);
- return isAddonIncluded(product, targetAddOnPlan);
- } catch (CatalogApiException e) {
- throw new SubscriptionBaseError(e);
- }
-
- }
-
- public boolean isAddonIncludedFromPlanName(final String basePlanName, final Plan targetAddOnPlan, final DateTime requestedDate, final Catalog catalog, final InternalTenantContext context) {
- try {
- final Plan plan = catalog.findPlan(basePlanName, requestedDate);
- final Product product = plan.getProduct();
- return isAddonIncluded(product, targetAddOnPlan);
- } catch (CatalogApiException e) {
- throw new SubscriptionBaseError(e);
- }
- }
-
- private boolean isAddonAvailable(final Product baseProduct, final Plan targetAddOnPlan) {
+ public boolean isAddonAvailable(final Product baseProduct, final Plan targetAddOnPlan) {
final Product targetAddonProduct = targetAddOnPlan.getProduct();
final Collection<Product> availableAddOns = baseProduct.getAvailable();
@@ -117,7 +65,7 @@ public class AddonUtils {
return false;
}
- private boolean isAddonIncluded(final Product baseProduct, final Plan targetAddOnPlan) {
+ public boolean isAddonIncluded(final Product baseProduct, final Plan targetAddOnPlan) {
final Product targetAddonProduct = targetAddOnPlan.getProduct();
final Collection<Product> includedAddOns = baseProduct.getIncluded();
for (final Product curAv : includedAddOns) {
@@ -128,7 +76,7 @@ public class AddonUtils {
return false;
}
- public int countExistingAddOnsWithSamePlanName(final Iterable<SubscriptionBase> subscriptionsForBundle, final String planName) {
+ public int countExistingAddOnsWithSamePlanName(final Iterable<DefaultSubscriptionBase> subscriptionsForBundle, final String planName) {
int countExistingAddOns = 0;
for (final SubscriptionBase subscription : subscriptionsForBundle) {
if (subscription.getCurrentPlan().getName().equalsIgnoreCase(planName)
diff --git a/subscription/src/main/java/org/killbill/billing/subscription/engine/dao/DefaultSubscriptionDao.java b/subscription/src/main/java/org/killbill/billing/subscription/engine/dao/DefaultSubscriptionDao.java
index 98ed638..2277355 100644
--- a/subscription/src/main/java/org/killbill/billing/subscription/engine/dao/DefaultSubscriptionDao.java
+++ b/subscription/src/main/java/org/killbill/billing/subscription/engine/dao/DefaultSubscriptionDao.java
@@ -43,6 +43,7 @@ import org.killbill.billing.callcontext.InternalTenantContext;
import org.killbill.billing.catalog.api.Catalog;
import org.killbill.billing.catalog.api.CatalogApiException;
import org.killbill.billing.catalog.api.Plan;
+import org.killbill.billing.catalog.api.Product;
import org.killbill.billing.catalog.api.ProductCategory;
import org.killbill.billing.entitlement.api.Entitlement.EntitlementState;
import org.killbill.billing.entitlement.api.SubscriptionApiException;
@@ -351,9 +352,9 @@ public class DefaultSubscriptionDao extends EntityDaoBase<SubscriptionBundleMode
@Override
public SubscriptionBase getSubscriptionFromId(final UUID subscriptionId, final Catalog catalog, final InternalTenantContext context) throws CatalogApiException {
- final SubscriptionBase shellSubscription = transactionalSqlDao.execute(true, new EntitySqlDaoTransactionWrapper<SubscriptionBase>() {
+ final DefaultSubscriptionBase shellSubscription = transactionalSqlDao.execute(true, new EntitySqlDaoTransactionWrapper<DefaultSubscriptionBase>() {
@Override
- public SubscriptionBase inTransaction(final EntitySqlDaoWrapperFactory entitySqlDaoWrapperFactory) throws Exception {
+ public DefaultSubscriptionBase inTransaction(final EntitySqlDaoWrapperFactory entitySqlDaoWrapperFactory) throws Exception {
final SubscriptionModelDao subscriptionModel = entitySqlDaoWrapperFactory.become(SubscriptionSqlDao.class).getById(subscriptionId.toString(), context);
final SubscriptionBundleModelDao bundleModel = entitySqlDaoWrapperFactory.become(BundleSqlDao.class).getById(subscriptionModel.getBundleId().toString(), context);
return SubscriptionModelDao.toSubscription(subscriptionModel, bundleModel.getExternalKey());
@@ -374,21 +375,21 @@ public class DefaultSubscriptionDao extends EntityDaoBase<SubscriptionBundleMode
}
@Override
- public List<SubscriptionBase> getSubscriptions(final UUID bundleId, final List<SubscriptionBaseEvent> dryRunEvents, final Catalog catalog, final InternalTenantContext context) throws CatalogApiException {
+ public List<DefaultSubscriptionBase> getSubscriptions(final UUID bundleId, final List<SubscriptionBaseEvent> dryRunEvents, final Catalog catalog, final InternalTenantContext context) throws CatalogApiException {
return buildBundleSubscriptions(getSubscriptionFromBundleId(bundleId, context), null, dryRunEvents, catalog, context);
}
- private List<SubscriptionBase> getSubscriptionFromBundleId(final UUID bundleId, final InternalTenantContext context) {
- return transactionalSqlDao.execute(true, new EntitySqlDaoTransactionWrapper<List<SubscriptionBase>>() {
+ private List<DefaultSubscriptionBase> getSubscriptionFromBundleId(final UUID bundleId, final InternalTenantContext context) {
+ return transactionalSqlDao.execute(true, new EntitySqlDaoTransactionWrapper<List<DefaultSubscriptionBase>>() {
@Override
- public List<SubscriptionBase> inTransaction(final EntitySqlDaoWrapperFactory entitySqlDaoWrapperFactory) throws Exception {
+ public List<DefaultSubscriptionBase> inTransaction(final EntitySqlDaoWrapperFactory entitySqlDaoWrapperFactory) throws Exception {
final SubscriptionBundleModelDao bundleModel = entitySqlDaoWrapperFactory.become(BundleSqlDao.class).getById(bundleId.toString(), context);
final List<SubscriptionModelDao> models = entitySqlDaoWrapperFactory.become(SubscriptionSqlDao.class).getSubscriptionsFromBundleId(bundleId.toString(), context);
- return new ArrayList<SubscriptionBase>(Collections2.transform(models, new Function<SubscriptionModelDao, SubscriptionBase>() {
+ return new ArrayList<DefaultSubscriptionBase>(Collections2.transform(models, new Function<SubscriptionModelDao, DefaultSubscriptionBase>() {
@Override
- public SubscriptionBase apply(@Nullable final SubscriptionModelDao input) {
+ public DefaultSubscriptionBase apply(@Nullable final SubscriptionModelDao input) {
return SubscriptionModelDao.toSubscription(input, bundleModel.getExternalKey());
}
}));
@@ -397,15 +398,15 @@ public class DefaultSubscriptionDao extends EntityDaoBase<SubscriptionBundleMode
}
@Override
- public Map<UUID, List<SubscriptionBase>> getSubscriptionsForAccount(final Catalog catalog, final InternalTenantContext context) throws CatalogApiException {
- final Map<UUID, List<SubscriptionBase>> subscriptionsFromAccountId = getSubscriptionsFromAccountId(context);
+ public Map<UUID, List<DefaultSubscriptionBase>> getSubscriptionsForAccount(final Catalog catalog, final InternalTenantContext context) throws CatalogApiException {
+ final Map<UUID, List<DefaultSubscriptionBase>> subscriptionsFromAccountId = getSubscriptionsFromAccountId(context);
final List<SubscriptionBaseEvent> eventsForAccount = getEventsForAccountId(context);
- final Map<UUID, List<SubscriptionBase>> result = new HashMap<UUID, List<SubscriptionBase>>();
+ final Map<UUID, List<DefaultSubscriptionBase>> result = new HashMap<UUID, List<DefaultSubscriptionBase>>();
for (final UUID bundleId : subscriptionsFromAccountId.keySet()) {
- final List<SubscriptionBase> subscriptionsForBundle = subscriptionsFromAccountId.get(bundleId);
+ final List<DefaultSubscriptionBase> subscriptionsForBundle = subscriptionsFromAccountId.get(bundleId);
final Multimap<UUID, SubscriptionBaseEvent> eventsForSubscriptions = ArrayListMultimap.create();
for (final SubscriptionBase cur : subscriptionsForBundle) {
@@ -424,17 +425,17 @@ public class DefaultSubscriptionDao extends EntityDaoBase<SubscriptionBundleMode
return result;
}
- private Map<UUID, List<SubscriptionBase>> getSubscriptionsFromAccountId(final InternalTenantContext context) {
- final List<SubscriptionBase> allSubscriptions = transactionalSqlDao.execute(true, new EntitySqlDaoTransactionWrapper<List<SubscriptionBase>>() {
+ private Map<UUID, List<DefaultSubscriptionBase>> getSubscriptionsFromAccountId(final InternalTenantContext context) {
+ final List<DefaultSubscriptionBase> allSubscriptions = transactionalSqlDao.execute(true, new EntitySqlDaoTransactionWrapper<List<DefaultSubscriptionBase>>() {
@Override
- public List<SubscriptionBase> inTransaction(final EntitySqlDaoWrapperFactory entitySqlDaoWrapperFactory) throws Exception {
+ public List<DefaultSubscriptionBase> inTransaction(final EntitySqlDaoWrapperFactory entitySqlDaoWrapperFactory) throws Exception {
final List<SubscriptionBundleModelDao> bundleModels = entitySqlDaoWrapperFactory.become(BundleSqlDao.class).getByAccountRecordId(context);
final List<SubscriptionModelDao> subscriptionModels = entitySqlDaoWrapperFactory.become(SubscriptionSqlDao.class).getByAccountRecordId(context);
- return new ArrayList<SubscriptionBase>(Collections2.transform(subscriptionModels, new Function<SubscriptionModelDao, SubscriptionBase>() {
+ return new ArrayList<DefaultSubscriptionBase>(Collections2.transform(subscriptionModels, new Function<SubscriptionModelDao, DefaultSubscriptionBase>() {
@Override
- public SubscriptionBase apply(final SubscriptionModelDao input) {
+ public DefaultSubscriptionBase apply(final SubscriptionModelDao input) {
final SubscriptionBundleModelDao bundleModel = Iterables.find(bundleModels, new Predicate<SubscriptionBundleModelDao>() {
@Override
public boolean apply(final SubscriptionBundleModelDao bundleInput) {
@@ -447,10 +448,10 @@ public class DefaultSubscriptionDao extends EntityDaoBase<SubscriptionBundleMode
}
});
- final Map<UUID, List<SubscriptionBase>> result = new HashMap<UUID, List<SubscriptionBase>>();
- for (final SubscriptionBase subscriptionBase : allSubscriptions) {
+ final Map<UUID, List<DefaultSubscriptionBase>> result = new HashMap<UUID, List<DefaultSubscriptionBase>>();
+ for (final DefaultSubscriptionBase subscriptionBase : allSubscriptions) {
if (result.get(subscriptionBase.getBundleId()) == null) {
- result.put(subscriptionBase.getBundleId(), new LinkedList<SubscriptionBase>());
+ result.put(subscriptionBase.getBundleId(), new LinkedList<DefaultSubscriptionBase>());
}
result.get(subscriptionBase.getBundleId()).add(subscriptionBase);
}
@@ -836,14 +837,14 @@ public class DefaultSubscriptionDao extends EntityDaoBase<SubscriptionBundleMode
}
}
- private SubscriptionBase buildSubscription(final SubscriptionBase input, final Catalog catalog, final InternalTenantContext context) throws CatalogApiException {
+ private DefaultSubscriptionBase buildSubscription(final DefaultSubscriptionBase input, final Catalog catalog, final InternalTenantContext context) throws CatalogApiException {
if (input == null) {
return null;
}
- final List<SubscriptionBase> bundleInput = new ArrayList<SubscriptionBase>();
+ final List<DefaultSubscriptionBase> bundleInput = new ArrayList<DefaultSubscriptionBase>();
if (input.getCategory() == ProductCategory.ADD_ON) {
- final SubscriptionBase baseSubscription = getBaseSubscription(input.getBundleId(), false, catalog, context);
+ final DefaultSubscriptionBase baseSubscription = getBaseSubscription(input.getBundleId(), false, catalog, context);
if (baseSubscription == null) {
return null;
}
@@ -854,8 +855,8 @@ public class DefaultSubscriptionDao extends EntityDaoBase<SubscriptionBundleMode
bundleInput.add(input);
}
- final List<SubscriptionBase> reloadedSubscriptions = buildBundleSubscriptions(bundleInput, null, null, catalog, context);
- for (final SubscriptionBase cur : reloadedSubscriptions) {
+ final List<DefaultSubscriptionBase> reloadedSubscriptions = buildBundleSubscriptions(bundleInput, null, null, catalog, context);
+ for (final DefaultSubscriptionBase cur : reloadedSubscriptions) {
if (cur.getId().equals(input.getId())) {
return cur;
}
@@ -864,7 +865,7 @@ public class DefaultSubscriptionDao extends EntityDaoBase<SubscriptionBundleMode
throw new SubscriptionBaseError("Unexpected code path in buildSubscription");
}
- private List<SubscriptionBase> buildBundleSubscriptions(final List<SubscriptionBase> input, @Nullable final Multimap<UUID, SubscriptionBaseEvent> eventsForSubscription,
+ private List<DefaultSubscriptionBase> buildBundleSubscriptions(final List<DefaultSubscriptionBase> input, @Nullable final Multimap<UUID, SubscriptionBaseEvent> eventsForSubscription,
@Nullable final Collection<SubscriptionBaseEvent> dryRunEvents, final Catalog catalog, final InternalTenantContext context) throws CatalogApiException {
if (input == null || input.isEmpty()) {
return Collections.emptyList();
@@ -875,14 +876,14 @@ public class DefaultSubscriptionDao extends EntityDaoBase<SubscriptionBundleMode
final Collection<ApiEventChange> baseChangeEvents = new LinkedList<ApiEventChange>();
ApiEventCancel baseCancellationEvent = null;
- final List<SubscriptionBase> result = new ArrayList<SubscriptionBase>(input.size());
- for (final SubscriptionBase cur : input) {
+ final List<DefaultSubscriptionBase> result = new ArrayList<DefaultSubscriptionBase>(input.size());
+ for (final DefaultSubscriptionBase cur : input) {
final List<SubscriptionBaseEvent> events = eventsForSubscription != null ?
(List<SubscriptionBaseEvent>) eventsForSubscription.get(cur.getId()) :
getEventsForSubscription(cur.getId(), context);
mergeDryRunEvents(cur.getId(), events, dryRunEvents);
- SubscriptionBase reloaded = createSubscriptionForInternalUse(cur, events, catalog, context);
+ DefaultSubscriptionBase reloaded = createSubscriptionForInternalUse(cur, events, catalog, context);
switch (cur.getCategory()) {
case BASE:
@@ -908,10 +909,11 @@ public class DefaultSubscriptionDao extends EntityDaoBase<SubscriptionBundleMode
SubscriptionBaseEvent baseTriggerEventForAddOnCancellation = baseCancellationEvent;
for (final ApiEventChange baseChangeEvent : baseChangeEvents) {
- final String baseProductName = baseChangeEvent.getEventPlan();
+ final Plan basePlan = catalog.findPlan(baseChangeEvent.getEventPlan(), baseChangeEvent.getEffectiveDate(), cur.getAlignStartDate());
+ final Product baseProduct = basePlan.getProduct();
- if ((!addonUtils.isAddonAvailableFromPlanName(baseProductName, targetAddOnPlan, baseChangeEvent.getEffectiveDate(), catalog, context)) ||
- (addonUtils.isAddonIncludedFromPlanName(baseProductName, targetAddOnPlan, baseChangeEvent.getEffectiveDate(), catalog, context))) {
+ if ((!addonUtils.isAddonAvailable(baseProduct, targetAddOnPlan)) ||
+ (addonUtils.isAddonIncluded(baseProduct, targetAddOnPlan))) {
if (baseTriggerEventForAddOnCancellation != null) {
if (baseTriggerEventForAddOnCancellation.getEffectiveDate().isAfter(baseChangeEvent.getEffectiveDate())) {
baseTriggerEventForAddOnCancellation = baseChangeEvent;
@@ -1051,7 +1053,7 @@ public class DefaultSubscriptionDao extends EntityDaoBase<SubscriptionBundleMode
}
- private SubscriptionBase createSubscriptionForInternalUse(final SubscriptionBase shellSubscription, final List<SubscriptionBaseEvent> events, final Catalog catalog, final InternalTenantContext context) throws CatalogApiException {
+ private DefaultSubscriptionBase createSubscriptionForInternalUse(final SubscriptionBase shellSubscription, final List<SubscriptionBaseEvent> events, final Catalog catalog, final InternalTenantContext context) throws CatalogApiException {
final DefaultSubscriptionBase result = new DefaultSubscriptionBase(new SubscriptionBuilder(((DefaultSubscriptionBase) shellSubscription)), null, clock);
if (!events.isEmpty()) {
@@ -1060,9 +1062,9 @@ public class DefaultSubscriptionDao extends EntityDaoBase<SubscriptionBundleMode
return result;
}
- private SubscriptionBase getBaseSubscription(final UUID bundleId, final boolean rebuildSubscription, final Catalog catalog, final InternalTenantContext context) throws CatalogApiException {
- final List<SubscriptionBase> subscriptions = getSubscriptionFromBundleId(bundleId, context);
- for (final SubscriptionBase cur : subscriptions) {
+ private DefaultSubscriptionBase getBaseSubscription(final UUID bundleId, final boolean rebuildSubscription, final Catalog catalog, final InternalTenantContext context) throws CatalogApiException {
+ final List<DefaultSubscriptionBase> subscriptions = getSubscriptionFromBundleId(bundleId, context);
+ for (final DefaultSubscriptionBase cur : subscriptions) {
if (cur.getCategory() == ProductCategory.BASE) {
return rebuildSubscription ? buildSubscription(cur, catalog, context) : cur;
}
diff --git a/subscription/src/main/java/org/killbill/billing/subscription/engine/dao/model/SubscriptionModelDao.java b/subscription/src/main/java/org/killbill/billing/subscription/engine/dao/model/SubscriptionModelDao.java
index e0761b9..d7adf33 100644
--- a/subscription/src/main/java/org/killbill/billing/subscription/engine/dao/model/SubscriptionModelDao.java
+++ b/subscription/src/main/java/org/killbill/billing/subscription/engine/dao/model/SubscriptionModelDao.java
@@ -105,7 +105,7 @@ public class SubscriptionModelDao extends EntityModelDaoBase implements EntityMo
this.migrated = migrated;
}
- public static SubscriptionBase toSubscription(final SubscriptionModelDao src, final String externalKey) {
+ public static DefaultSubscriptionBase toSubscription(final SubscriptionModelDao src, final String externalKey) {
if (src == null) {
return null;
}
diff --git a/subscription/src/main/java/org/killbill/billing/subscription/engine/dao/SubscriptionDao.java b/subscription/src/main/java/org/killbill/billing/subscription/engine/dao/SubscriptionDao.java
index 242676b..64fdc9a 100644
--- a/subscription/src/main/java/org/killbill/billing/subscription/engine/dao/SubscriptionDao.java
+++ b/subscription/src/main/java/org/killbill/billing/subscription/engine/dao/SubscriptionDao.java
@@ -64,9 +64,9 @@ public interface SubscriptionDao extends EntityDao<SubscriptionBundleModelDao, S
// SubscriptionBase retrieval
public SubscriptionBase getBaseSubscription(UUID bundleId, final Catalog catalog, InternalTenantContext context) throws CatalogApiException;
- public List<SubscriptionBase> getSubscriptions(UUID bundleId, List<SubscriptionBaseEvent> dryRunEvents, final Catalog catalog, InternalTenantContext context) throws CatalogApiException;
+ public List<DefaultSubscriptionBase> getSubscriptions(UUID bundleId, List<SubscriptionBaseEvent> dryRunEvents, final Catalog catalog, InternalTenantContext context) throws CatalogApiException;
- public Map<UUID, List<SubscriptionBase>> getSubscriptionsForAccount(final Catalog catalog, InternalTenantContext context) throws CatalogApiException;
+ public Map<UUID, List<DefaultSubscriptionBase>> getSubscriptionsForAccount(final Catalog catalog, InternalTenantContext context) throws CatalogApiException;
// Update
public void updateChargedThroughDate(DefaultSubscriptionBase subscription, InternalCallContext context);
diff --git a/subscription/src/test/java/org/killbill/billing/subscription/api/user/TestUserApiAddOn.java b/subscription/src/test/java/org/killbill/billing/subscription/api/user/TestUserApiAddOn.java
index ba21e92..4999f00 100644
--- a/subscription/src/test/java/org/killbill/billing/subscription/api/user/TestUserApiAddOn.java
+++ b/subscription/src/test/java/org/killbill/billing/subscription/api/user/TestUserApiAddOn.java
@@ -400,10 +400,11 @@ public class TestUserApiAddOn extends SubscriptionTestSuiteWithEmbeddedDB {
final PlanSpecifier planSpecifier = new PlanSpecifier(aoProduct,
aoTerm,
aoPriceList);
- final PlanAlignmentCreate alignement = catalog.planCreateAlignment(planSpecifier, clock.getUTCNow());
- assertEquals(alignement, PlanAlignmentCreate.START_OF_BUNDLE);
+ final DateTime utcNow = clock.getUTCNow();
+ final PlanAlignmentCreate alignment = catalog.planCreateAlignment(planSpecifier, utcNow, utcNow);
+ assertEquals(alignment, PlanAlignmentCreate.START_OF_BUNDLE);
- testAddonCreateInternal(aoProduct, aoTerm, aoPriceList, alignement);
+ testAddonCreateInternal(aoProduct, aoTerm, aoPriceList, alignment);
}
@Test(groups = "slow")
@@ -416,10 +417,11 @@ public class TestUserApiAddOn extends SubscriptionTestSuiteWithEmbeddedDB {
final PlanSpecifier planSpecifier = new PlanSpecifier(aoProduct,
aoTerm,
aoPriceList);
- final PlanAlignmentCreate alignement = catalog.planCreateAlignment(planSpecifier, clock.getUTCNow());
- assertEquals(alignement, PlanAlignmentCreate.START_OF_SUBSCRIPTION);
+ final DateTime utcNow = clock.getUTCNow();
+ final PlanAlignmentCreate alignment = catalog.planCreateAlignment(planSpecifier, utcNow, utcNow);
+ assertEquals(alignment, PlanAlignmentCreate.START_OF_SUBSCRIPTION);
- testAddonCreateInternal(aoProduct, aoTerm, aoPriceList, alignement);
+ testAddonCreateInternal(aoProduct, aoTerm, aoPriceList, alignment);
}
private void testAddonCreateInternal(final String aoProduct, final BillingPeriod aoTerm, final String aoPriceList, final PlanAlignmentCreate expAlignement) throws SubscriptionBaseApiException {
diff --git a/subscription/src/test/java/org/killbill/billing/subscription/engine/dao/MockSubscriptionDaoMemory.java b/subscription/src/test/java/org/killbill/billing/subscription/engine/dao/MockSubscriptionDaoMemory.java
index 8b5a74e..36b05f0 100644
--- a/subscription/src/test/java/org/killbill/billing/subscription/engine/dao/MockSubscriptionDaoMemory.java
+++ b/subscription/src/test/java/org/killbill/billing/subscription/engine/dao/MockSubscriptionDaoMemory.java
@@ -78,7 +78,7 @@ public class MockSubscriptionDaoMemory extends MockEntityDaoBase<SubscriptionBun
protected static final Logger log = LoggerFactory.getLogger(SubscriptionDao.class);
private final List<SubscriptionBaseBundle> bundles;
- private final List<SubscriptionBase> subscriptions;
+ private final List<DefaultSubscriptionBase> subscriptions;
private final TreeSet<SubscriptionBaseEvent> events;
private final MockNonEntityDao mockNonEntityDao;
@@ -100,7 +100,7 @@ public class MockSubscriptionDaoMemory extends MockEntityDaoBase<SubscriptionBun
this.notificationQueueService = notificationQueueService;
this.eventBus = eventBus;
this.bundles = new ArrayList<SubscriptionBaseBundle>();
- this.subscriptions = new ArrayList<SubscriptionBase>();
+ this.subscriptions = new ArrayList<DefaultSubscriptionBase>();
this.events = new TreeSet<SubscriptionBaseEvent>();
}
@@ -216,7 +216,7 @@ public class MockSubscriptionDaoMemory extends MockEntityDaoBase<SubscriptionBun
for (final SubscriptionBaseEvent cur : initialEvents) {
recordFutureNotificationFromTransaction(null, cur.getEffectiveDate(), new SubscriptionNotificationKey(cur.getId()), context);
}
- final SubscriptionBase updatedSubscription = buildSubscription((DefaultSubscriptionBase) subscriptionBase, context);
+ final DefaultSubscriptionBase updatedSubscription = buildSubscription((DefaultSubscriptionBase) subscriptionBase, context);
this.subscriptions.add(updatedSubscription);
mockNonEntityDao.addTenantRecordIdMapping(updatedSubscription.getId(), context);
@@ -229,24 +229,24 @@ public class MockSubscriptionDaoMemory extends MockEntityDaoBase<SubscriptionBun
}
@Override
- public List<SubscriptionBase> getSubscriptions(final UUID bundleId, final List<SubscriptionBaseEvent> dryRunEvents, final Catalog catalog, final InternalTenantContext context) {
- final List<SubscriptionBase> results = new ArrayList<SubscriptionBase>();
- for (final SubscriptionBase cur : subscriptions) {
+ public List<DefaultSubscriptionBase> getSubscriptions(final UUID bundleId, final List<SubscriptionBaseEvent> dryRunEvents, final Catalog catalog, final InternalTenantContext context) {
+ final List<DefaultSubscriptionBase> results = new ArrayList<DefaultSubscriptionBase>();
+ for (final DefaultSubscriptionBase cur : subscriptions) {
if (cur.getBundleId().equals(bundleId)) {
- results.add(buildSubscription((DefaultSubscriptionBase) cur, context));
+ results.add(buildSubscription(cur, context));
}
}
return results;
}
@Override
- public Map<UUID, List<SubscriptionBase>> getSubscriptionsForAccount(final Catalog catalog, final InternalTenantContext context) {
- final Map<UUID, List<SubscriptionBase>> results = new HashMap<UUID, List<SubscriptionBase>>();
- for (final SubscriptionBase cur : subscriptions) {
+ public Map<UUID, List<DefaultSubscriptionBase>> getSubscriptionsForAccount(final Catalog catalog, final InternalTenantContext context) {
+ final Map<UUID, List<DefaultSubscriptionBase>> results = new HashMap<UUID, List<DefaultSubscriptionBase>>();
+ for (final DefaultSubscriptionBase cur : subscriptions) {
if (results.get(cur.getBundleId()) == null) {
- results.put(cur.getBundleId(), new LinkedList<SubscriptionBase>());
+ results.put(cur.getBundleId(), new LinkedList<DefaultSubscriptionBase>());
}
- results.get(cur.getBundleId()).add(buildSubscription((DefaultSubscriptionBase) cur, context));
+ results.get(cur.getBundleId()).add(buildSubscription(cur, context));
}
return results;
}
@@ -297,9 +297,9 @@ public class MockSubscriptionDaoMemory extends MockEntityDaoBase<SubscriptionBun
notifyBusOfEffectiveImmediateChange(subscription, readyPhaseEvent, 0, context);
}
- private SubscriptionBase buildSubscription(final DefaultSubscriptionBase in, final InternalTenantContext context) {
+ private DefaultSubscriptionBase buildSubscription(final DefaultSubscriptionBase in, final InternalTenantContext context) {
final DefaultSubscriptionBase subscription = new DefaultSubscriptionBase(new SubscriptionBuilder(in), null, clock);
- if (events.size() > 0) {
+ if (!events.isEmpty()) {
try {
subscription.rebuildTransitions(getEventsForSubscription(in.getId(), context), catalogService.getFullCatalog(true, true, context));
} catch (final CatalogApiException e) {
@@ -307,13 +307,12 @@ public class MockSubscriptionDaoMemory extends MockEntityDaoBase<SubscriptionBun
}
}
return subscription;
-
}
@Override
public void updateChargedThroughDate(final DefaultSubscriptionBase subscription, final InternalCallContext context) {
boolean found = false;
- final Iterator<SubscriptionBase> it = subscriptions.iterator();
+ final Iterator<DefaultSubscriptionBase> it = subscriptions.iterator();
while (it.hasNext()) {
final SubscriptionBase cur = it.next();
if (cur.getId().equals(subscription.getId())) {
diff --git a/subscription/src/test/java/org/killbill/billing/subscription/engine/dao/TestSubscriptionDao.java b/subscription/src/test/java/org/killbill/billing/subscription/engine/dao/TestSubscriptionDao.java
index c3bb42a..7ca3747 100644
--- a/subscription/src/test/java/org/killbill/billing/subscription/engine/dao/TestSubscriptionDao.java
+++ b/subscription/src/test/java/org/killbill/billing/subscription/engine/dao/TestSubscriptionDao.java
@@ -77,6 +77,9 @@ public class TestSubscriptionDao extends SubscriptionTestSuiteWithEmbeddedDB {
@Override // to ignore events
@AfterMethod(groups = "slow")
public void afterMethod() throws Exception {
+ if (hasFailed()) {
+ return;
+ }
subscriptionTestInitializer.stopTestFramework(testListener, busService, subscriptionBaseService);
}
diff --git a/util/src/test/java/org/killbill/billing/api/TestApiListener.java b/util/src/test/java/org/killbill/billing/api/TestApiListener.java
index 83cb4c2..b431636 100644
--- a/util/src/test/java/org/killbill/billing/api/TestApiListener.java
+++ b/util/src/test/java/org/killbill/billing/api/TestApiListener.java
@@ -324,8 +324,12 @@ public class TestApiListener {
} catch (final Exception ignore) {
// Rerun one more time to provide details
final long pending = idbi.withHandle(new PendingBusOrNotificationCallback(clock));
- log.error("isCompleted : Received all events but found remaining unprocessed bus events/notifications = {}", pending);
- return false;
+ if (pending != 0) {
+ log.error("isCompleted : Received all events but found remaining unprocessed bus events/notifications = {}", pending);
+ return false;
+ } else {
+ return completed;
+ }
}
} while (waitTimeMs > 0 && !completed);
}