killbill-memoizeit
Changes
.github/CONTRIBUTING.md 3(+1 -2)
api/src/main/java/org/killbill/billing/subscription/api/SubscriptionBaseInternalApi.java 25(+11 -14)
api/src/main/java/org/killbill/billing/subscription/api/SubscriptionBaseWithAddOnsSpecifier.java 76(+76 -0)
beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestCatalogRetireElements.java 10(+7 -3)
beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestIntegrationDryRunInvoice.java 16(+9 -7)
beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestIntegrationWithCatalogUpdate.java 17(+10 -7)
beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestInvoiceNotifications.java 10(+6 -4)
beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestMigrationSubscriptions.java 45(+24 -21)
entitlement/src/main/java/org/killbill/billing/entitlement/api/DefaultEntitlementApi.java 171(+63 -108)
entitlement/src/main/java/org/killbill/billing/entitlement/api/DefaultSubscriptionApi.java 11(+5 -6)
entitlement/src/main/java/org/killbill/billing/entitlement/block/DefaultBlockingChecker.java 39(+18 -21)
entitlement/src/main/java/org/killbill/billing/entitlement/dao/OptimizedProxyBlockingStateDao.java 3(+3 -0)
entitlement/src/main/java/org/killbill/billing/entitlement/engine/core/DefaultEventsStream.java 9(+6 -3)
entitlement/src/main/java/org/killbill/billing/entitlement/engine/core/EntitlementUtils.java 2(+1 -1)
entitlement/src/main/java/org/killbill/billing/entitlement/engine/core/EventsStreamBuilder.java 37(+30 -7)
entitlement/src/test/java/org/killbill/billing/entitlement/api/TestDefaultEntitlement.java 31(+20 -11)
entitlement/src/test/java/org/killbill/billing/entitlement/api/TestDefaultEntitlementApi.java 78(+51 -27)
entitlement/src/test/java/org/killbill/billing/entitlement/api/TestDefaultSubscriptionApi.java 53(+32 -21)
entitlement/src/test/java/org/killbill/billing/entitlement/api/TestRegessionSubscriptionApi.java 23(+4 -19)
entitlement/src/test/java/org/killbill/billing/entitlement/dao/TestDefaultBlockingStateDao.java 3(+2 -1)
entitlement/src/test/java/org/killbill/billing/entitlement/engine/core/TestEntitlementUtils.java 13(+8 -5)
invoice/src/main/java/org/killbill/billing/invoice/notification/DefaultNextBillingDateNotifier.java 23(+6 -17)
junction/src/test/java/org/killbill/billing/junction/plumbing/billing/TestDefaultInternalBillingApi.java 11(+7 -4)
pom.xml 2(+1 -1)
subscription/src/main/java/org/killbill/billing/subscription/api/SubscriptionBaseApiService.java 17(+2 -15)
subscription/src/main/java/org/killbill/billing/subscription/api/svcs/DefaultSubscriptionInternalApi.java 278(+175 -103)
subscription/src/main/java/org/killbill/billing/subscription/api/user/DefaultSubscriptionBaseApiService.java 33(+9 -24)
subscription/src/main/java/org/killbill/billing/subscription/api/user/DefaultSubscriptionBaseWithAddOns.java 13(+1 -12)
subscription/src/main/java/org/killbill/billing/subscription/engine/dao/DefaultSubscriptionDao.java 62(+4 -58)
subscription/src/main/java/org/killbill/billing/subscription/engine/dao/SubscriptionDao.java 6(+1 -5)
subscription/src/main/java/org/killbill/billing/subscription/engine/dao/SubscriptionEventSqlDao.java 9(+4 -5)
subscription/src/main/resources/org/killbill/billing/subscription/engine/dao/SubscriptionEventSqlDao.sql.stg 13(+0 -13)
subscription/src/test/java/org/killbill/billing/subscription/api/user/TestSubscriptionHelper.java 117(+98 -19)
subscription/src/test/java/org/killbill/billing/subscription/api/user/TestUserApiCancel.java 23(+9 -14)
subscription/src/test/java/org/killbill/billing/subscription/api/user/TestUserApiChangePlan.java 6(+3 -3)
subscription/src/test/java/org/killbill/billing/subscription/api/user/TestUserApiCreate.java 64(+15 -49)
subscription/src/test/java/org/killbill/billing/subscription/api/user/TestUserApiError.java 44(+10 -34)
subscription/src/test/java/org/killbill/billing/subscription/DefaultSubscriptionTestInitializer.java 8(+4 -4)
subscription/src/test/java/org/killbill/billing/subscription/engine/dao/MockSubscriptionDaoMemory.java 56(+17 -39)
subscription/src/test/java/org/killbill/billing/subscription/engine/dao/TestSubscriptionDao.java 15(+12 -3)
subscription/src/test/java/org/killbill/billing/subscription/SubscriptionTestInitializer.java 2(+1 -1)
subscription/src/test/java/org/killbill/billing/subscription/SubscriptionTestSuiteNoDB.java 26(+21 -5)
subscription/src/test/java/org/killbill/billing/subscription/SubscriptionTestSuiteWithEmbeddedDB.java 7(+4 -3)
Details
.github/CONTRIBUTING.md 3(+1 -2)
diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md
index 01715d6..20451a4 100644
--- a/.github/CONTRIBUTING.md
+++ b/.github/CONTRIBUTING.md
@@ -7,8 +7,7 @@
In your [Mailing-List](https://groups.google.com/forum/#!forum/killbilling-users) post, specify:
* Step by step description on how to reproduce the issue
-* [Account data dump](https://github.com/killbill/killbill/wiki/Production-troubleshooting#exporting-account-data) of an affected account
-* [System information](https://github.com/killbill/killbill/wiki/Production-troubleshooting#exporting-system-information)
+* [Account data and system dump](https://github.com/killbill/killbill/wiki/Production-troubleshooting#debugging-issues) of an affected account
#### **Do you intend to add a new feature or change an existing one?**
diff --git a/api/src/main/java/org/killbill/billing/subscription/api/SubscriptionBaseInternalApi.java b/api/src/main/java/org/killbill/billing/subscription/api/SubscriptionBaseInternalApi.java
index ac9f05f..ac1df1a 100644
--- a/api/src/main/java/org/killbill/billing/subscription/api/SubscriptionBaseInternalApi.java
+++ b/api/src/main/java/org/killbill/billing/subscription/api/SubscriptionBaseInternalApi.java
@@ -33,7 +33,6 @@ import org.killbill.billing.catalog.api.Catalog;
import org.killbill.billing.catalog.api.CatalogApiException;
import org.killbill.billing.catalog.api.PlanPhasePriceOverride;
import org.killbill.billing.catalog.api.PlanPhaseSpecifier;
-import org.killbill.billing.entitlement.api.BaseEntitlementWithAddOnsSpecifier;
import org.killbill.billing.entitlement.api.EntitlementAOStatusDryRun;
import org.killbill.billing.events.EffectiveSubscriptionInternalEvent;
import org.killbill.billing.invoice.api.DryRunArguments;
@@ -43,20 +42,14 @@ import org.killbill.billing.util.entity.Pagination;
public interface SubscriptionBaseInternalApi {
- public SubscriptionBase createSubscription(SubscriptionBaseBundle bundle,
- @Nullable SubscriptionBase baseSubscription,
- PlanPhaseSpecifier spec,
- List<PlanPhasePriceOverride> overrides,
- DateTime requestedDateWithMs,
- boolean isMigrated,
- InternalCallContext context) throws SubscriptionBaseApiException;
-
- public List<SubscriptionBaseWithAddOns> createBaseSubscriptionsWithAddOns(UUID accountId, Iterable<BaseEntitlementWithAddOnsSpecifier> baseEntitlementWithAddOnsSpecifier,
- boolean renameCancelledBundleIfExist, InternalCallContext contextWithValidAccountRecordId) throws SubscriptionBaseApiException;
+ public List<SubscriptionBaseWithAddOns> createBaseSubscriptionsWithAddOns(Iterable<SubscriptionBaseWithAddOnsSpecifier> subscriptionWithAddOnsSpecifiers,
+ boolean renameCancelledBundleIfExist,
+ InternalCallContext contextWithValidAccountRecordId) throws SubscriptionBaseApiException;
public void cancelBaseSubscriptions(Iterable<SubscriptionBase> subscriptions, BillingActionPolicy policy, int accountBillCycleDayLocal, InternalCallContext context) throws SubscriptionBaseApiException;
- public SubscriptionBaseBundle createBundleForAccount(UUID accountId, String bundleName, boolean renameCancelledBundleIfExist, InternalCallContext context)
+ //@VisibleForTesting
+ SubscriptionBaseBundle createBundleForAccount(UUID accountId, String bundleName, boolean renameCancelledBundleIfExist, InternalCallContext context)
throws SubscriptionBaseApiException;
public List<SubscriptionBaseBundle> getBundlesForAccountAndKey(UUID accountId, String bundleKey, InternalTenantContext context)
@@ -83,8 +76,6 @@ public interface SubscriptionBaseInternalApi {
public SubscriptionBaseBundle getBundleFromId(UUID id, InternalTenantContext context) throws SubscriptionBaseApiException;
- public UUID getAccountIdFromSubscriptionId(UUID subscriptionId, InternalTenantContext context) throws SubscriptionBaseApiException;
-
public void setChargedThroughDate(UUID subscriptionId, DateTime chargedThruDate, InternalCallContext context) throws SubscriptionBaseApiException;
public List<EffectiveSubscriptionInternalEvent> getAllTransitions(SubscriptionBase subscription, InternalTenantContext context);
@@ -101,4 +92,10 @@ public interface SubscriptionBaseInternalApi {
public void updateBCD(final UUID subscriptionId, final int bcd, @Nullable final LocalDate effectiveFromDate, final InternalCallContext internalCallContext) throws SubscriptionBaseApiException;
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;
+
+ public UUID getAccountIdFromBundleId(UUID bundleId, InternalTenantContext context) throws SubscriptionBaseApiException;
+
+ public UUID getBundleIdFromSubscriptionId(UUID entitlementId, InternalTenantContext context) throws SubscriptionBaseApiException;
+
+ public UUID getAccountIdFromSubscriptionId(UUID subscriptionId, InternalTenantContext context) throws SubscriptionBaseApiException;
}
diff --git a/api/src/main/java/org/killbill/billing/subscription/api/SubscriptionBaseWithAddOns.java b/api/src/main/java/org/killbill/billing/subscription/api/SubscriptionBaseWithAddOns.java
index 3fc0da9..1ad70ad 100644
--- a/api/src/main/java/org/killbill/billing/subscription/api/SubscriptionBaseWithAddOns.java
+++ b/api/src/main/java/org/killbill/billing/subscription/api/SubscriptionBaseWithAddOns.java
@@ -19,7 +19,6 @@ package org.killbill.billing.subscription.api;
import java.util.List;
-import org.joda.time.DateTime;
import org.killbill.billing.subscription.api.user.SubscriptionBaseBundle;
public interface SubscriptionBaseWithAddOns {
@@ -27,6 +26,4 @@ public interface SubscriptionBaseWithAddOns {
public SubscriptionBaseBundle getBundle();
public List<SubscriptionBase> getSubscriptionBaseList();
-
- public DateTime getEffectiveDate();
}
diff --git a/api/src/main/java/org/killbill/billing/subscription/api/SubscriptionBaseWithAddOnsSpecifier.java b/api/src/main/java/org/killbill/billing/subscription/api/SubscriptionBaseWithAddOnsSpecifier.java
new file mode 100644
index 0000000..e6a7099
--- /dev/null
+++ b/api/src/main/java/org/killbill/billing/subscription/api/SubscriptionBaseWithAddOnsSpecifier.java
@@ -0,0 +1,76 @@
+/*
+ * 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
+ * License. You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.killbill.billing.subscription.api;
+
+import java.util.UUID;
+
+import org.joda.time.DateTime;
+import org.killbill.billing.entitlement.api.EntitlementSpecifier;
+
+public class SubscriptionBaseWithAddOnsSpecifier {
+
+ private final UUID bundleId;
+ private final String bundleExternalKey;
+ private final Iterable<EntitlementSpecifier> entitlementSpecifiers;
+ private final DateTime billingEffectiveDate;
+ private final boolean isMigrated;
+
+ public SubscriptionBaseWithAddOnsSpecifier(final UUID bundleId,
+ final String bundleExternalKey,
+ final Iterable<EntitlementSpecifier> entitlementSpecifiers,
+ final DateTime billingEffectiveDate,
+ final boolean isMigrated) {
+ this.bundleId = bundleId;
+ this.bundleExternalKey = bundleExternalKey;
+ this.entitlementSpecifiers = entitlementSpecifiers;
+ this.billingEffectiveDate = billingEffectiveDate;
+ this.isMigrated = isMigrated;
+ }
+
+ public UUID getBundleId() {
+ return bundleId;
+ }
+
+ public String getBundleExternalKey() {
+ return bundleExternalKey;
+ }
+
+ public Iterable<EntitlementSpecifier> getEntitlementSpecifiers() {
+ return entitlementSpecifiers;
+ }
+
+ public DateTime getBillingEffectiveDate() {
+ return billingEffectiveDate;
+ }
+
+ public boolean isMigrated() {
+ return isMigrated;
+ }
+
+ @Override
+ public String toString() {
+ final StringBuilder sb = new StringBuilder("SubscriptionBaseWithAddOnsSpecifier{");
+ sb.append("bundleId=").append(bundleId);
+ sb.append(", bundleExternalKey='").append(bundleExternalKey).append('\'');
+ sb.append(", entitlementSpecifiers=").append(entitlementSpecifiers);
+ sb.append(", billingEffectiveDate=").append(billingEffectiveDate);
+ sb.append(", isMigrated=").append(isMigrated);
+ sb.append('}');
+ return sb.toString();
+ }
+}
diff --git a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestCatalogRetireElements.java b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestCatalogRetireElements.java
index 357cef0..0f3c7e1 100644
--- a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestCatalogRetireElements.java
+++ b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestCatalogRetireElements.java
@@ -18,6 +18,7 @@
package org.killbill.billing.beatrix.integration;
import java.util.List;
+import java.util.UUID;
import org.joda.time.LocalDate;
import org.killbill.billing.ErrorCode;
@@ -192,8 +193,9 @@ public class TestCatalogRetireElements extends TestIntegrationBase {
final PlanPhaseSpecifier spec1 = new PlanPhaseSpecifier(productName, term, "DEFAULT", null);
busHandler.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK, NextEvent.INVOICE);
- Entitlement bpEntitlement = entitlementApi.createBaseEntitlement(account.getId(), spec1, "externalKey", null, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID bpEntitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec1, "externalKey", null, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
+ Entitlement bpEntitlement = entitlementApi.getEntitlementForId(bpEntitlementId, callContext);
assertNotNull(bpEntitlement);
assertEquals(bpEntitlement.getLastActivePhase().getPhaseType(), PhaseType.TRIAL);
@@ -282,8 +284,9 @@ public class TestCatalogRetireElements extends TestIntegrationBase {
final PlanPhaseSpecifier spec1 = new PlanPhaseSpecifier(productName, term, "DEFAULT", null);
busHandler.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK, NextEvent.INVOICE);
- Entitlement bpEntitlement = entitlementApi.createBaseEntitlement(account.getId(), spec1, "externalKey", null, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID bpEntitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec1, "externalKey", null, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
+ Entitlement bpEntitlement = entitlementApi.getEntitlementForId(bpEntitlementId, callContext);
assertNotNull(bpEntitlement);
assertEquals(bpEntitlement.getLastActivePhase().getPhaseType(), PhaseType.TRIAL);
@@ -440,8 +443,9 @@ public class TestCatalogRetireElements extends TestIntegrationBase {
final PlanPhaseSpecifier spec = new PlanPhaseSpecifier(productName, term, "SpecialDiscount", null);
busHandler.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK, NextEvent.INVOICE);
- final Entitlement bpEntitlement = entitlementApi.createBaseEntitlement(account.getId(), spec, "externalKey", null, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID bpEntitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, "externalKey", null, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
+ final Entitlement bpEntitlement = entitlementApi.getEntitlementForId(bpEntitlementId, callContext);
assertNotNull(bpEntitlement);
assertEquals(invoiceUserApi.getInvoicesByAccount(account.getId(), false, false, callContext).size(), 1);
diff --git a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestIntegrationBase.java b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestIntegrationBase.java
index 4b040d1..4e8ecce 100644
--- a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestIntegrationBase.java
+++ b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestIntegrationBase.java
@@ -659,9 +659,9 @@ public class TestIntegrationBase extends BeatrixTestSuiteWithEmbeddedDB implemen
public Entitlement apply(@Nullable final Void dontcare) {
try {
final PlanPhaseSpecifier spec = new PlanPhaseSpecifier(productName, billingPeriod, PriceListSet.DEFAULT_PRICELIST_NAME, null);
- final Entitlement entitlement = entitlementApi.createBaseEntitlement(accountId, spec, bundleExternalKey, overrides, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
- assertNotNull(entitlement);
- return entitlement;
+ final UUID entitlementId = entitlementApi.createBaseEntitlement(accountId, spec, bundleExternalKey, overrides, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ assertNotNull(entitlementId);
+ return entitlementApi.getEntitlementForId(entitlementId, callContext);
} catch (final EntitlementApiException e) {
fail("Unable to create entitlement", e);
return null;
@@ -693,9 +693,9 @@ public class TestIntegrationBase extends BeatrixTestSuiteWithEmbeddedDB implemen
public Entitlement apply(@Nullable final Void dontcare) {
try {
final PlanPhaseSpecifier spec = new PlanPhaseSpecifier(productName, billingPeriod, PriceListSet.DEFAULT_PRICELIST_NAME, null);
- final Entitlement entitlement = entitlementApi.addEntitlement(bundleId, spec, null, null, null, false, ImmutableList.<PluginProperty>of(), callContext);
- assertNotNull(entitlement);
- return entitlement;
+ final UUID entitlementId = entitlementApi.addEntitlement(bundleId, spec, null, null, null, false, ImmutableList.<PluginProperty>of(), callContext);
+ assertNotNull(entitlementId);
+ return entitlementApi.getEntitlementForId(entitlementId, callContext);
} catch (final EntitlementApiException e) {
fail(e.getMessage());
return null;
diff --git a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestIntegrationDryRunInvoice.java b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestIntegrationDryRunInvoice.java
index 14b2100..9107ffe 100644
--- a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestIntegrationDryRunInvoice.java
+++ b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestIntegrationDryRunInvoice.java
@@ -1,6 +1,6 @@
/*
- * 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
@@ -20,6 +20,7 @@ package org.killbill.billing.beatrix.integration;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
+import java.util.UUID;
import org.joda.time.DateTime;
import org.joda.time.LocalDate;
@@ -27,10 +28,8 @@ import org.killbill.billing.ErrorCode;
import org.killbill.billing.account.api.Account;
import org.killbill.billing.api.TestApiListener.NextEvent;
import org.killbill.billing.beatrix.util.InvoiceChecker.ExpectedInvoiceItemCheck;
-import org.killbill.billing.catalog.DefaultPlanPhasePriceOverride;
import org.killbill.billing.catalog.api.BillingActionPolicy;
import org.killbill.billing.catalog.api.BillingPeriod;
-import org.killbill.billing.catalog.api.PlanPhasePriceOverride;
import org.killbill.billing.catalog.api.PlanPhaseSpecifier;
import org.killbill.billing.catalog.api.PriceListSet;
import org.killbill.billing.catalog.api.ProductCategory;
@@ -242,7 +241,8 @@ public class TestIntegrationDryRunInvoice extends TestIntegrationBase {
final LocalDate futureDate = new LocalDate(2017, 5, 1);
// No CREATE event as this is set in the future
- final Entitlement createdEntitlement = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, futureDate, futureDate, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID createdEntitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, futureDate, futureDate, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final Entitlement createdEntitlement = entitlementApi.getEntitlementForId(createdEntitlementId, callContext);
assertEquals(createdEntitlement.getState(), Entitlement.EntitlementState.PENDING);
assertEquals(createdEntitlement.getEffectiveStartDate().compareTo(futureDate), 0);
assertEquals(createdEntitlement.getEffectiveEndDate(), null);
@@ -319,7 +319,8 @@ public class TestIntegrationDryRunInvoice extends TestIntegrationBase {
final LocalDate futureStartDate = new LocalDate(2017, 5, 1);
// No CREATE event as this is set in the future
- final Entitlement createdEntitlement = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, futureStartDate, futureStartDate, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID createdEntitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, futureStartDate, futureStartDate, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final Entitlement createdEntitlement = entitlementApi.getEntitlementForId(createdEntitlementId, callContext);
assertEquals(createdEntitlement.getState(), Entitlement.EntitlementState.PENDING);
assertEquals(createdEntitlement.getEffectiveStartDate().compareTo(futureStartDate), 0);
assertEquals(createdEntitlement.getEffectiveEndDate(), null);
@@ -446,8 +447,9 @@ public class TestIntegrationDryRunInvoice extends TestIntegrationBase {
// No CREATE event as this is set in the future
busHandler.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK, NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("pistol-monthly-notrial", null);
- final Entitlement baseEntitlement = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID baseEntitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
+ final Entitlement baseEntitlement = entitlementApi.getEntitlementForId(baseEntitlementId, callContext);
final DefaultEntitlement aoEntitlement = addAOEntitlementAndCheckForCompletion(baseEntitlement.getBundleId(), "Refurbish-Maintenance", ProductCategory.ADD_ON, BillingPeriod.MONTHLY, NextEvent.CREATE, NextEvent.BLOCK, NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
diff --git a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestIntegrationInvoice.java b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestIntegrationInvoice.java
index 5f92da5..d203881 100644
--- a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestIntegrationInvoice.java
+++ b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestIntegrationInvoice.java
@@ -216,8 +216,9 @@ public class TestIntegrationInvoice extends TestIntegrationBase {
final List<PlanPhasePriceOverride> overrides = new ArrayList<PlanPhasePriceOverride>();
overrides.add(new DefaultPlanPhasePriceOverride("blowdart-monthly-notrial-evergreen", account.getCurrency(), null, BigDecimal.ZERO, ImmutableList.<UsagePriceOverride>of()));
busHandler.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK, NextEvent.INVOICE);
- final Entitlement entitlement = entitlementApi.createBaseEntitlement(account.getId(), spec, "bundleExternalKey", overrides, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, "bundleExternalKey", overrides, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
+ final Entitlement entitlement = entitlementApi.getEntitlementForId(entitlementId, callContext);
invoiceChecker.checkInvoice(account.getId(), 1, callContext,
new ExpectedInvoiceItemCheck(new LocalDate(2017, 1, 1), new LocalDate(2017, 2, 1), InvoiceItemType.RECURRING, BigDecimal.ZERO));
diff --git a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestIntegrationWithCatalogUpdate.java b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestIntegrationWithCatalogUpdate.java
index 05f4d5e..05931c8 100644
--- a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestIntegrationWithCatalogUpdate.java
+++ b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestIntegrationWithCatalogUpdate.java
@@ -1,6 +1,6 @@
/*
- * 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
@@ -283,8 +283,9 @@ public class TestIntegrationWithCatalogUpdate extends TestIntegrationBase {
final PlanPhaseSpecifier specZero = new PlanPhaseSpecifier("zeroDesc-monthly", null);
busHandler.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK, NextEvent.INVOICE);
- final Entitlement baseEntitlement = entitlementApi.createBaseEntitlement(account.getId(), specZero, UUID.randomUUID().toString(), ImmutableList.<PlanPhasePriceOverride>of(), null, null, false, true, ImmutableList.<PluginProperty>of(), testCallContext);
+ final UUID baseEntitlementId = entitlementApi.createBaseEntitlement(account.getId(), specZero, UUID.randomUUID().toString(), ImmutableList.<PlanPhasePriceOverride>of(), null, null, false, true, ImmutableList.<PluginProperty>of(), testCallContext);
assertListenerStatus();
+ final Entitlement baseEntitlement = entitlementApi.getEntitlementForId(baseEntitlementId, testCallContext);
Subscription refreshedBaseEntitlement = subscriptionApi.getSubscriptionForEntitlementId(baseEntitlement.getId(), testCallContext);
assertEquals(refreshedBaseEntitlement.getChargedThroughDate(), new LocalDate(2016, 7, 1));
@@ -312,8 +313,9 @@ public class TestIntegrationWithCatalogUpdate extends TestIntegrationBase {
final PlanPhaseSpecifier specNonZero = new PlanPhaseSpecifier("superfoo-monthly", null);
busHandler.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK, NextEvent.INVOICE, NextEvent.INVOICE_PAYMENT, NextEvent.PAYMENT);
- final Entitlement baseEntitlement2 = entitlementApi.createBaseEntitlement(account.getId(), specNonZero, UUID.randomUUID().toString(), ImmutableList.<PlanPhasePriceOverride>of(), null, null, false, true, ImmutableList.<PluginProperty>of(), testCallContext);
+ final UUID baseEntitlement2Id = entitlementApi.createBaseEntitlement(account.getId(), specNonZero, UUID.randomUUID().toString(), ImmutableList.<PlanPhasePriceOverride>of(), null, null, false, true, ImmutableList.<PluginProperty>of(), testCallContext);
assertListenerStatus();
+ final Entitlement baseEntitlement2 = entitlementApi.getEntitlementForId(baseEntitlement2Id, testCallContext);
busHandler.pushExpectedEvents(NextEvent.INVOICE, NextEvent.INVOICE_PAYMENT, NextEvent.PAYMENT);
clock.addMonths(1);
@@ -373,8 +375,9 @@ public class TestIntegrationWithCatalogUpdate extends TestIntegrationBase {
final PlanPhaseSpecifier planPhaseSpec = new PlanPhaseSpecifier("hello-monthly", null);
busHandler.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK, NextEvent.INVOICE);
- final Entitlement baseEntitlement = entitlementApi.createBaseEntitlement(account.getId(), planPhaseSpec, UUID.randomUUID().toString(), ImmutableList.<PlanPhasePriceOverride>of(), null, null, false, true, ImmutableList.<PluginProperty>of(), testCallContext);
+ final UUID baseEntitlementId = entitlementApi.createBaseEntitlement(account.getId(), planPhaseSpec, UUID.randomUUID().toString(), ImmutableList.<PlanPhasePriceOverride>of(), null, null, false, true, ImmutableList.<PluginProperty>of(), testCallContext);
assertListenerStatus();
+ final Entitlement baseEntitlement = entitlementApi.getEntitlementForId(baseEntitlementId, testCallContext);
Subscription refreshedBaseEntitlement = subscriptionApi.getSubscriptionForEntitlementId(baseEntitlement.getId(), testCallContext);
assertEquals(refreshedBaseEntitlement.getChargedThroughDate(), new LocalDate(2016, 6, 1));
@@ -407,9 +410,9 @@ public class TestIntegrationWithCatalogUpdate extends TestIntegrationBase {
} else {
busHandler.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK, NextEvent.INVOICE);
}
- final Entitlement entitlement = entitlementApi.createBaseEntitlement(account.getId(), spec, UUID.randomUUID().toString(), overrides, null, null, false, true, ImmutableList.<PluginProperty>of(), testCallContext);
+ final UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, UUID.randomUUID().toString(), overrides, null, null, false, true, ImmutableList.<PluginProperty>of(), testCallContext);
assertListenerStatus();
- return entitlement;
+ return entitlementApi.getEntitlementForId(entitlementId, testCallContext);
}
private void setupTenant() throws TenantApiException {
diff --git a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestInvoiceNotifications.java b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestInvoiceNotifications.java
index 1b8b3ed..7cbed63 100644
--- a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestInvoiceNotifications.java
+++ b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestInvoiceNotifications.java
@@ -1,6 +1,6 @@
/*
- * 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
@@ -17,13 +17,14 @@
package org.killbill.billing.beatrix.integration;
+import java.util.UUID;
+
import org.joda.time.LocalDate;
import org.killbill.billing.account.api.Account;
import org.killbill.billing.account.api.AccountData;
import org.killbill.billing.api.TestApiListener.NextEvent;
import org.killbill.billing.catalog.api.BillingPeriod;
import org.killbill.billing.catalog.api.PlanPhaseSpecifier;
-import org.killbill.billing.catalog.api.PriceListSet;
import org.killbill.billing.catalog.api.ProductCategory;
import org.killbill.billing.entitlement.api.DefaultEntitlement;
import org.killbill.billing.entitlement.api.Entitlement;
@@ -84,8 +85,9 @@ public class TestInvoiceNotifications extends TestIntegrationBase {
busHandler.pushExpectedEvents(NextEvent.BLOCK);
- final Entitlement entitlement = entitlementApi.createBaseEntitlement(account.getId(), spec, "bundleKey", null, null, billingDate, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, "bundleKey", null, null, billingDate, false, true, ImmutableList.<PluginProperty>of(), callContext);
busHandler.assertListenerStatus();
+ final Entitlement entitlement = entitlementApi.getEntitlementForId(entitlementId, callContext);
// Move to the notification before the start date => 2018, 2, 21
addDaysAndCheckForCompletion(21, NextEvent.INVOICE_NOTIFICATION);
diff --git a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestMigrationSubscriptions.java b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestMigrationSubscriptions.java
index 049f602..072f857 100644
--- a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestMigrationSubscriptions.java
+++ b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestMigrationSubscriptions.java
@@ -1,6 +1,6 @@
/*
- * 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
@@ -86,7 +86,8 @@ public class TestMigrationSubscriptions extends TestIntegrationBase {
// Entitlement wil be created in PENDING state
final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Shotgun", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null);
- final Entitlement entitlement = entitlementApi.createBaseEntitlement(account.getId(), spec, "bundleKey", null, entitlementMigrationDate, billingMigrationDate, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, "bundleKey", null, entitlementMigrationDate, billingMigrationDate, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final Entitlement entitlement = entitlementApi.getEntitlementForId(entitlementId, callContext);
Assert.assertEquals(entitlement.getState(), EntitlementState.PENDING);
// Move clock to entitlementMigrationDate (migration cutOverDate), and expect the associated event
@@ -142,8 +143,9 @@ public class TestMigrationSubscriptions extends TestIntegrationBase {
// Entitlement wil be created in ACTIVE state because entitlementMigrationDate was set in the past
busHandler.pushExpectedEvents(NextEvent.BLOCK);
final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Shotgun", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, PhaseType.EVERGREEN);
- final Entitlement entitlement = entitlementApi.createBaseEntitlement(account.getId(), spec, "bundleKey", null, entitlementMigrationDate, billingMigrationDate, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, "bundleKey", null, entitlementMigrationDate, billingMigrationDate, false, true, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
+ final Entitlement entitlement = entitlementApi.getEntitlementForId(entitlementId, callContext);
Assert.assertEquals(entitlement.getState(), EntitlementState.ACTIVE);
@@ -187,8 +189,9 @@ public class TestMigrationSubscriptions extends TestIntegrationBase {
// Entitlement wil be created in ACTIVE state because entitlementMigrationDate was set in the past
busHandler.pushExpectedEvents(NextEvent.BLOCK);
final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Shotgun", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, PhaseType.EVERGREEN);
- final Entitlement entitlement = entitlementApi.createBaseEntitlement(account.getId(), spec, "bundleKey", null, entitlementMigrationDate, billingMigrationDate, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, "bundleKey", null, entitlementMigrationDate, billingMigrationDate, false, true, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
+ final Entitlement entitlement = entitlementApi.getEntitlementForId(entitlementId, callContext);
Assert.assertEquals(entitlement.getState(), EntitlementState.ACTIVE);
// Perform the cancellation (we did not move the clock, the is is future cancellation done at the time we decide to migrate)
@@ -253,14 +256,14 @@ public class TestMigrationSubscriptions extends TestIntegrationBase {
List<BaseEntitlementWithAddOnsSpecifier> baseEntitlementWithAddOnsSpecifierList = new ArrayList<BaseEntitlementWithAddOnsSpecifier>();
baseEntitlementWithAddOnsSpecifierList.add(baseEntitlementWithAddOnsSpecifier);
- final List<Entitlement> baseEntitlements = entitlementApi.createBaseEntitlementsWithAddOns(
- account.getId(),
- baseEntitlementWithAddOnsSpecifierList,
- true,
- ImmutableList.<PluginProperty>of(),
- callContext);
+ final List<UUID> baseEntitlements = entitlementApi.createBaseEntitlementsWithAddOns(account.getId(),
+ baseEntitlementWithAddOnsSpecifierList,
+ true,
+ ImmutableList.<PluginProperty>of(),
+ callContext);
assertListenerStatus();
- Assert.assertEquals(baseEntitlements.get(0).getState(), EntitlementState.ACTIVE);
+ final Entitlement entitlement = entitlementApi.getEntitlementForId(baseEntitlements.get(0), callContext);
+ Assert.assertEquals(entitlement.getState(), EntitlementState.ACTIVE);
// Billing starts straight on EVERGREEN
clock.addMonths(1);
@@ -306,15 +309,14 @@ public class TestMigrationSubscriptions extends TestIntegrationBase {
baseEntitlementWithAddOnsSpecifierList.add(baseEntitlementWithAddOnsSpecifierBundle1);
baseEntitlementWithAddOnsSpecifierList.add(baseEntitlementWithAddOnsSpecifierBundle2);
- final List<Entitlement> baseEntitlements = entitlementApi.createBaseEntitlementsWithAddOns(
- account.getId(),
- baseEntitlementWithAddOnsSpecifierList,
- true,
- ImmutableList.<PluginProperty>of(),
- callContext);
+ final List<UUID> baseEntitlements = entitlementApi.createBaseEntitlementsWithAddOns(account.getId(),
+ baseEntitlementWithAddOnsSpecifierList,
+ true,
+ ImmutableList.<PluginProperty>of(),
+ callContext);
assertListenerStatus();
- Assert.assertEquals(baseEntitlements.get(0).getState(), EntitlementState.ACTIVE);
- Assert.assertEquals(baseEntitlements.get(1).getState(), EntitlementState.ACTIVE);
+ Assert.assertEquals(entitlementApi.getEntitlementForId(baseEntitlements.get(0), callContext).getState(), EntitlementState.ACTIVE);
+ Assert.assertEquals(entitlementApi.getEntitlementForId(baseEntitlements.get(1), callContext).getState(), EntitlementState.ACTIVE);
// Billing starts straight on EVERGREEN for Bundle 1 after 1 month
clock.addMonths(1);
@@ -466,8 +468,9 @@ public class TestMigrationSubscriptions extends TestIntegrationBase {
final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("pistol-monthly-notrial", null);
busHandler.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK);
- final Entitlement baseEntitlement = entitlementApi.createBaseEntitlement(account.getId(), spec, "bundleExternalKey", ImmutableList.<PlanPhasePriceOverride>of(), null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID baseEntitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, "bundleExternalKey", ImmutableList.<PlanPhasePriceOverride>of(), null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
+ final Entitlement baseEntitlement = entitlementApi.getEntitlementForId(baseEntitlementId, callContext);
clock.addDays(1);
diff --git a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestSubscription.java b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestSubscription.java
index df2cecf..c4edb51 100644
--- a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestSubscription.java
+++ b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestSubscription.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
@@ -21,6 +21,7 @@ package org.killbill.billing.beatrix.integration;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
+import java.util.UUID;
import org.joda.time.DateTimeZone;
import org.joda.time.LocalDate;
@@ -235,16 +236,16 @@ public class TestSubscription extends TestIntegrationBase {
NextEvent.INVOICE,
NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT
);
- final List<Entitlement> allEntitlements = entitlementApi.createBaseEntitlementsWithAddOns(account.getId(), entitlementWithAddOnsSpecifierList, true, ImmutableList.<PluginProperty>of(), callContext);
+ final List<UUID> allEntitlements = entitlementApi.createBaseEntitlementsWithAddOns(account.getId(), entitlementWithAddOnsSpecifierList, true, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
checkNoMoreInvoiceToGenerate(account);
assertNotNull(allEntitlements);
assertEquals(allEntitlements.size(), 6);
- final Entitlement baseEntitlement = allEntitlements.get(0);
- final Entitlement addOnEntitlement1 = allEntitlements.get(1);
- final Entitlement addOnEntitlement2 = allEntitlements.get(2);
+ final Entitlement baseEntitlement = entitlementApi.getEntitlementForId(allEntitlements.get(0), callContext);
+ final Entitlement addOnEntitlement1 = entitlementApi.getEntitlementForId(allEntitlements.get(1), callContext);
+ final Entitlement addOnEntitlement2 = entitlementApi.getEntitlementForId(allEntitlements.get(2), callContext);
assertEquals(baseEntitlement.getLastActiveProduct().getName(), "Shotgun");
assertEquals(baseEntitlement.getLastActiveProductCategory(), ProductCategory.BASE);
@@ -319,7 +320,7 @@ public class TestSubscription extends TestIntegrationBase {
NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT
);
- final List<Entitlement> entitlements = entitlementApi.createBaseEntitlementsWithAddOns(account.getId(), entitlementWithAddOnsSpecifierList, true, ImmutableList.<PluginProperty>of(), callContext);
+ final List<UUID> entitlements = entitlementApi.createBaseEntitlementsWithAddOns(account.getId(), entitlementWithAddOnsSpecifierList, true, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
Assert.assertEquals(entitlements.size(), 5);
@@ -417,8 +418,9 @@ public class TestSubscription extends TestIntegrationBase {
// Create third add_on subscription with another plan
busHandler.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK, NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
- Entitlement addOn3 = entitlementApi.addEntitlement(baseEntitlement.getBundleId(), addOnSpec3, null, initialDate, initialDate, false, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID addOn3Id = entitlementApi.addEntitlement(baseEntitlement.getBundleId(), addOnSpec3, null, initialDate, initialDate, false, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
+ final Entitlement addOn3 = entitlementApi.getEntitlementForId(addOn3Id, callContext);
// Trying to change the plan of the third add_on to 'Laser-Scope' plan, should throw an exception (the limit is 2 for this plan)
try {
@@ -441,7 +443,8 @@ public class TestSubscription extends TestIntegrationBase {
final LocalDate futureDate = new LocalDate(2015, 10, 1);
// No CREATE event as this is set in the future
- final Entitlement createdEntitlement = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, futureDate, futureDate, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID createdEntitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, futureDate, futureDate, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final Entitlement createdEntitlement = entitlementApi.getEntitlementForId(createdEntitlementId, callContext);
assertEquals(createdEntitlement.getEffectiveStartDate().compareTo(futureDate), 0);
assertEquals(createdEntitlement.getEffectiveEndDate(), null);
assertListenerStatus();
@@ -473,7 +476,8 @@ public class TestSubscription extends TestIntegrationBase {
final LocalDate futureDate = new LocalDate(2015, 10, 1);
// No CREATE event as this is set in the future
- final Entitlement createdEntitlement = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, futureDate, futureDate, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID createdEntitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, futureDate, futureDate, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final Entitlement createdEntitlement = entitlementApi.getEntitlementForId(createdEntitlementId, callContext);
assertEquals(createdEntitlement.getState(), EntitlementState.PENDING);
assertEquals(createdEntitlement.getEffectiveStartDate().compareTo(futureDate), 0);
assertEquals(createdEntitlement.getEffectiveEndDate(), null);
@@ -517,7 +521,8 @@ public class TestSubscription extends TestIntegrationBase {
final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Shotgun", BillingPeriod.ANNUAL, PriceListSet.DEFAULT_PRICELIST_NAME, null);
busHandler.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK, NextEvent.INVOICE);
- final Entitlement createdEntitlement = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, initialDate, initialDate, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID createdEntitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, initialDate, initialDate, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final Entitlement createdEntitlement = entitlementApi.getEntitlementForId(createdEntitlementId, callContext);
assertEquals(createdEntitlement.getEffectiveStartDate().compareTo(initialDate), 0);
assertEquals(createdEntitlement.getEffectiveEndDate(), null);
assertListenerStatus();
@@ -546,7 +551,8 @@ public class TestSubscription extends TestIntegrationBase {
final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Shotgun", BillingPeriod.ANNUAL, PriceListSet.DEFAULT_PRICELIST_NAME, null);
busHandler.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK, NextEvent.INVOICE);
- final Entitlement createdEntitlement = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, initialDate, initialDate, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID createdEntitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, initialDate, initialDate, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final Entitlement createdEntitlement = entitlementApi.getEntitlementForId(createdEntitlementId, callContext);
assertEquals(createdEntitlement.getEffectiveStartDate().compareTo(initialDate), 0);
assertEquals(createdEntitlement.getEffectiveEndDate(), null);
assertListenerStatus();
diff --git a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestWithBCDUpdate.java b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestWithBCDUpdate.java
index 783f8af..1ad2a6a 100644
--- a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestWithBCDUpdate.java
+++ b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestWithBCDUpdate.java
@@ -1,6 +1,6 @@
/*
- * 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
@@ -20,6 +20,7 @@ package org.killbill.billing.beatrix.integration;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
+import java.util.UUID;
import javax.inject.Inject;
@@ -33,7 +34,6 @@ import org.killbill.billing.catalog.api.BillingActionPolicy;
import org.killbill.billing.catalog.api.BillingPeriod;
import org.killbill.billing.catalog.api.PlanPhasePriceOverride;
import org.killbill.billing.catalog.api.PlanPhaseSpecifier;
-import org.killbill.billing.catalog.api.PlanSpecifier;
import org.killbill.billing.catalog.api.ProductCategory;
import org.killbill.billing.catalog.api.UsagePriceOverride;
import org.killbill.billing.entitlement.api.BlockingState;
@@ -572,8 +572,9 @@ public class TestWithBCDUpdate extends TestIntegrationBase {
overrides.add(new DefaultPlanPhasePriceOverride("blowdart-monthly-notrial-evergreen", account.getCurrency(), null, BigDecimal.ZERO, ImmutableList.<UsagePriceOverride>of()));
busHandler.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK, NextEvent.INVOICE);
// BP creation : Will set Account BCD to the first (DateOfFirstRecurringNonZeroCharge is the subscription start date in this case)
- final Entitlement baseEntitlement = entitlementApi.createBaseEntitlement(account.getId(), spec, "bundleExternalKey", overrides, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID baseEntitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, "bundleExternalKey", overrides, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
+ final Entitlement baseEntitlement = entitlementApi.getEntitlementForId(baseEntitlementId, callContext);
invoiceChecker.checkInvoice(account.getId(), 1, callContext,
new ExpectedInvoiceItemCheck(new LocalDate(2016, 4, 1), new LocalDate(2016, 5, 1), InvoiceItemType.RECURRING, BigDecimal.ZERO));
@@ -634,8 +635,9 @@ public class TestWithBCDUpdate extends TestIntegrationBase {
overrides.add(new DefaultPlanPhasePriceOverride("blowdart-monthly-notrial-evergreen", account.getCurrency(), null, BigDecimal.ZERO, ImmutableList.<UsagePriceOverride>of()));
busHandler.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK, NextEvent.INVOICE);
// BP creation : Will set Account BCD to the first (DateOfFirstRecurringNonZeroCharge is the subscription start date in this case)
- final Entitlement baseEntitlement = entitlementApi.createBaseEntitlement(account.getId(), spec, "bundleExternalKey", overrides, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID baseEntitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, "bundleExternalKey", overrides, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
+ final Entitlement baseEntitlement = entitlementApi.getEntitlementForId(baseEntitlementId, callContext);
invoiceChecker.checkInvoice(account.getId(), 1, callContext,
new ExpectedInvoiceItemCheck(new LocalDate(2016, 5, 1), new LocalDate(2016, 6, 1), InvoiceItemType.RECURRING, BigDecimal.ZERO));
@@ -692,8 +694,9 @@ public class TestWithBCDUpdate extends TestIntegrationBase {
overrides.add(new DefaultPlanPhasePriceOverride("blowdart-monthly-notrial-evergreen", account.getCurrency(), null, BigDecimal.ZERO, ImmutableList.<UsagePriceOverride>of()));
busHandler.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK, NextEvent.INVOICE);
// BP creation : Will set Account BCD to the first (DateOfFirstRecurringNonZeroCharge is the subscription start date in this case)
- final Entitlement baseEntitlement = entitlementApi.createBaseEntitlement(account.getId(), spec, "bundleExternalKey", overrides, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID baseEntitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, "bundleExternalKey", overrides, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
+ final Entitlement baseEntitlement = entitlementApi.getEntitlementForId(baseEntitlementId, callContext);
invoiceChecker.checkInvoice(account.getId(), 1, callContext,
new ExpectedInvoiceItemCheck(new LocalDate(2016, 4, 1), new LocalDate(2016, 5, 1), InvoiceItemType.RECURRING, BigDecimal.ZERO));
diff --git a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestWithTimeZones.java b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestWithTimeZones.java
index 9d1e86a..6ca9f1b 100644
--- a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestWithTimeZones.java
+++ b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestWithTimeZones.java
@@ -1,6 +1,6 @@
/*
- * 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
@@ -138,8 +138,9 @@ public class TestWithTimeZones extends TestIntegrationBase {
busHandler.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK, NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Blowdart", BillingPeriod.MONTHLY, "notrial", null);
- Entitlement entitlement = entitlementApi.createBaseEntitlement(account.getId(), spec, "Something", ImmutableList.<PlanPhasePriceOverride>of(), null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, "Something", ImmutableList.<PlanPhasePriceOverride>of(), null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
+ Entitlement entitlement = entitlementApi.getEntitlementForId(entitlementId, callContext);
// Cancel the next month specifying just a LocalDate
final LocalDate cancellationDate = new LocalDate("2015-12-01", tz);
@@ -184,8 +185,9 @@ public class TestWithTimeZones extends TestIntegrationBase {
busHandler.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK, NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Blowdart", BillingPeriod.MONTHLY, "notrial", null);
- Entitlement entitlement = entitlementApi.createBaseEntitlement(account.getId(), spec, "Something", ImmutableList.<PlanPhasePriceOverride>of(), null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, "Something", ImmutableList.<PlanPhasePriceOverride>of(), null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
+ Entitlement entitlement = entitlementApi.getEntitlementForId(entitlementId, callContext);
// Cancel the next month specifying just a LocalDate
final LocalDate cancellationDate = new LocalDate("2015-03-01", tz);
@@ -238,8 +240,9 @@ public class TestWithTimeZones extends TestIntegrationBase {
busHandler.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK, NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Blowdart", BillingPeriod.MONTHLY, "notrial", null);
// Pass a date of today, to trigger TimeAwareContext#toUTCDateTime
- final Entitlement entitlement = entitlementApi.createBaseEntitlement(account.getId(), spec, "Something", ImmutableList.<PlanPhasePriceOverride>of(), clock.getUTCToday(), clock.getUTCToday(), false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, "Something", ImmutableList.<PlanPhasePriceOverride>of(), clock.getUTCToday(), clock.getUTCToday(), false, true, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
+ final Entitlement entitlement = entitlementApi.getEntitlementForId(entitlementId, callContext);
Assert.assertEquals(entitlement.getEffectiveStartDate().compareTo(new LocalDate("2015-03-08")), 0);
Assert.assertEquals(((DefaultEntitlement) entitlement).getBasePlanSubscriptionBase().getStartDate().compareTo(new DateTime("2015-03-08T02:00:00.000-08:00")), 0);
diff --git a/entitlement/src/main/java/org/killbill/billing/entitlement/api/DefaultEntitlementApi.java b/entitlement/src/main/java/org/killbill/billing/entitlement/api/DefaultEntitlementApi.java
index 42356de..a5e8793 100644
--- a/entitlement/src/main/java/org/killbill/billing/entitlement/api/DefaultEntitlementApi.java
+++ b/entitlement/src/main/java/org/killbill/billing/entitlement/api/DefaultEntitlementApi.java
@@ -19,8 +19,10 @@
package org.killbill.billing.entitlement.api;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
+import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.UUID;
@@ -57,6 +59,7 @@ import org.killbill.billing.security.api.SecurityApi;
import org.killbill.billing.subscription.api.SubscriptionBase;
import org.killbill.billing.subscription.api.SubscriptionBaseInternalApi;
import org.killbill.billing.subscription.api.SubscriptionBaseWithAddOns;
+import org.killbill.billing.subscription.api.SubscriptionBaseWithAddOnsSpecifier;
import org.killbill.billing.subscription.api.transfer.SubscriptionBaseTransferApi;
import org.killbill.billing.subscription.api.transfer.SubscriptionBaseTransferApiException;
import org.killbill.billing.subscription.api.user.SubscriptionBaseApiException;
@@ -124,9 +127,9 @@ public class DefaultEntitlementApi extends DefaultEntitlementApiBase implements
}
@Override
- public Entitlement createBaseEntitlement(final UUID accountId, final PlanPhaseSpecifier planPhaseSpecifier, final String externalKey, final List<PlanPhasePriceOverride> overrides,
- @Nullable final LocalDate entitlementEffectiveDate, @Nullable final LocalDate billingEffectiveDate, final boolean isMigrated, final boolean renameCancelledBundleIfExist,
- final Iterable<PluginProperty> properties, final CallContext callContext) throws EntitlementApiException {
+ public UUID createBaseEntitlement(final UUID accountId, final PlanPhaseSpecifier planPhaseSpecifier, final String externalKey, final List<PlanPhasePriceOverride> overrides,
+ @Nullable final LocalDate entitlementEffectiveDate, @Nullable final LocalDate billingEffectiveDate, final boolean isMigrated, final boolean renameCancelledBundleIfExist,
+ final Iterable<PluginProperty> properties, final CallContext callContext) throws EntitlementApiException {
final EntitlementSpecifier entitlementSpecifier = new DefaultEntitlementSpecifier(planPhaseSpecifier, overrides);
final BaseEntitlementWithAddOnsSpecifier baseEntitlementWithAddOnsSpecifier = new DefaultBaseEntitlementWithAddOnsSpecifier(null,
externalKey,
@@ -134,12 +137,12 @@ public class DefaultEntitlementApi extends DefaultEntitlementApiBase implements
entitlementEffectiveDate,
billingEffectiveDate,
isMigrated);
- final List<Entitlement> baseEntitlementsWithAddOns = createBaseEntitlementsWithAddOns(accountId,
- ImmutableList.<BaseEntitlementWithAddOnsSpecifier>of(baseEntitlementWithAddOnsSpecifier),
- renameCancelledBundleIfExist,
- properties,
- callContext);
- return baseEntitlementsWithAddOns.get(0);
+ final List<UUID> createdEntitlements = createBaseEntitlementsWithAddOns(accountId,
+ ImmutableList.<BaseEntitlementWithAddOnsSpecifier>of(baseEntitlementWithAddOnsSpecifier),
+ renameCancelledBundleIfExist,
+ properties,
+ callContext);
+ return createdEntitlements.get(0);
}
private BaseEntitlementWithAddOnsSpecifier getFirstBaseEntitlementWithAddOnsSpecifier(final Iterable<BaseEntitlementWithAddOnsSpecifier> baseEntitlementWithAddOnsSpecifiers) throws SubscriptionBaseApiException {
@@ -155,16 +158,8 @@ public class DefaultEntitlementApi extends DefaultEntitlementApiBase implements
return iterator.next();
}
- private EntitlementSpecifier getFirstEntitlementSpecifier(final BaseEntitlementWithAddOnsSpecifier entitlementWithAddOnsSpecifier) throws SubscriptionBaseApiException {
- if (entitlementWithAddOnsSpecifier.getEntitlementSpecifier() == null || !entitlementWithAddOnsSpecifier.getEntitlementSpecifier().iterator().hasNext()) {
- throw new SubscriptionBaseApiException(ErrorCode.SUB_CREATE_INVALID_ENTITLEMENT_SPECIFIER);
- } else {
- return entitlementWithAddOnsSpecifier.getEntitlementSpecifier().iterator().next();
- }
- }
-
@Override
- public List<Entitlement> createBaseEntitlementsWithAddOns(final UUID accountId, final Iterable<BaseEntitlementWithAddOnsSpecifier> originalBaseEntitlementWithAddOnsSpecifiers, final boolean renameCancelledBundleIfExist, final Iterable<PluginProperty> properties, final CallContext callContext) throws EntitlementApiException {
+ public List<UUID> createBaseEntitlementsWithAddOns(final UUID accountId, final Iterable<BaseEntitlementWithAddOnsSpecifier> originalBaseEntitlementWithAddOnsSpecifiers, final boolean renameCancelledBundleIfExist, final Iterable<PluginProperty> properties, final CallContext callContext) throws EntitlementApiException {
logCreateEntitlementsWithAOs(log, originalBaseEntitlementWithAddOnsSpecifiers);
final EntitlementContext pluginContext = new DefaultEntitlementContext(OperationType.CREATE_SHOPPING_CART_SUBSCRIPTIONS,
@@ -175,13 +170,14 @@ public class DefaultEntitlementApi extends DefaultEntitlementApiBase implements
properties,
callContext);
- final WithEntitlementPlugin<List<Entitlement>> createBaseEntitlementsWithAddOns = new WithEntitlementPlugin<List<Entitlement>>() {
+ final WithEntitlementPlugin<List<UUID>> createBaseEntitlementsWithAddOns = new WithEntitlementPlugin<List<UUID>>() {
@Override
- public List<Entitlement> doCall(final EntitlementApi entitlementApi, final EntitlementContext updatedPluginContext) throws EntitlementApiException {
+ public List<UUID> doCall(final EntitlementApi entitlementApi, final EntitlementContext updatedPluginContext) throws EntitlementApiException {
final InternalCallContext contextWithValidAccountRecordId = internalCallContextFactory.createInternalCallContext(accountId, callContext);
final DateTime now = clock.getUTCNow();
final Iterable<BaseEntitlementWithAddOnsSpecifier> baseEntitlementWithAddOnsSpecifiersAfterPlugins = updatedPluginContext.getBaseEntitlementWithAddOnsSpecifiers();
+ final Collection<SubscriptionBaseWithAddOnsSpecifier> subscriptionBaseWithAddOnsSpecifiers = new LinkedList<SubscriptionBaseWithAddOnsSpecifier>();
DateTime upTo = null;
for (final BaseEntitlementWithAddOnsSpecifier baseEntitlementWithAddOnsSpecifier : baseEntitlementWithAddOnsSpecifiersAfterPlugins) {
// Entitlement
@@ -189,6 +185,15 @@ public class DefaultEntitlementApi extends DefaultEntitlementApiBase implements
now,
contextWithValidAccountRecordId);
upTo = upTo == null || upTo.compareTo(entitlementRequestedDate) < 0 ? entitlementRequestedDate : upTo;
+
+ final DateTime billingEffectiveDateTime = (baseEntitlementWithAddOnsSpecifier.getBillingEffectiveDate() != null) ?
+ contextWithValidAccountRecordId.toUTCDateTime(baseEntitlementWithAddOnsSpecifier.getBillingEffectiveDate()) : null;
+ final SubscriptionBaseWithAddOnsSpecifier subscriptionBaseWithAddOnsSpecifier = new SubscriptionBaseWithAddOnsSpecifier(baseEntitlementWithAddOnsSpecifier.getBundleId(),
+ baseEntitlementWithAddOnsSpecifier.getExternalKey(),
+ baseEntitlementWithAddOnsSpecifier.getEntitlementSpecifier(),
+ billingEffectiveDateTime,
+ baseEntitlementWithAddOnsSpecifier.isMigrated());
+ subscriptionBaseWithAddOnsSpecifiers.add(subscriptionBaseWithAddOnsSpecifier);
}
try {
@@ -196,10 +201,10 @@ public class DefaultEntitlementApi extends DefaultEntitlementApiBase implements
// Note that to fully check for block_change we should also look for BlockingState at the BUNDLE/SUBSCRIPTION level in case some of the input contain a BP that already exists.
checkForAccountBlockingChange(accountId, upTo, contextWithValidAccountRecordId);
- final List<SubscriptionBaseWithAddOns> subscriptionsWithAddOns = subscriptionBaseInternalApi.createBaseSubscriptionsWithAddOns(accountId,
- baseEntitlementWithAddOnsSpecifiersAfterPlugins,
- renameCancelledBundleIfExist,
- contextWithValidAccountRecordId);
+ final List<SubscriptionBaseWithAddOns> subscriptionsWithAddOns = subscriptionBaseInternalApi.createBaseSubscriptionsWithAddOns(subscriptionBaseWithAddOnsSpecifiers,
+ renameCancelledBundleIfExist,
+ contextWithValidAccountRecordId);
+ final List<UUID> createdSubscriptionIds = new LinkedList<UUID>();
final Map<BlockingState, UUID> blockingStateMap = new HashMap<BlockingState, UUID>();
int i = 0;
for (final Iterator<BaseEntitlementWithAddOnsSpecifier> it = baseEntitlementWithAddOnsSpecifiersAfterPlugins.iterator(); it.hasNext(); i++) {
@@ -214,10 +219,12 @@ public class DefaultEntitlementApi extends DefaultEntitlementApiBase implements
false,
dateHelper.fromLocalDateAndReferenceTime(baseEntitlementWithAddOnsSpecifier.getEntitlementEffectiveDate(), now, contextWithValidAccountRecordId));
blockingStateMap.put(blockingState, subscriptionsWithAddOns.get(i).getBundle().getId());
+
+ createdSubscriptionIds.add(subscriptionBase.getId());
}
}
entitlementUtils.setBlockingStateAndPostBlockingTransitionEvent(blockingStateMap, contextWithValidAccountRecordId);
- return buildEntitlementList(subscriptionsWithAddOns, contextWithValidAccountRecordId);
+ return createdSubscriptionIds;
} catch (final SubscriptionBaseApiException e) {
throw new EntitlementApiException(e);
}
@@ -226,40 +233,9 @@ public class DefaultEntitlementApi extends DefaultEntitlementApiBase implements
return pluginExecution.executeWithPlugin(createBaseEntitlementsWithAddOns, pluginContext);
}
- private List<Entitlement> buildEntitlementList(final Iterable<SubscriptionBaseWithAddOns> subscriptionsWithAddOns, final InternalCallContext internalCallContext) throws EntitlementApiException {
- // Need to refresh all latest state as some bundles might have existed already
- final AccountEventsStreams accountEventsStreams = eventsStreamBuilder.buildForAccount(internalCallContext);
-
- final List<Entitlement> result = new ArrayList<Entitlement>();
- for (final SubscriptionBaseWithAddOns subscriptionWithAddOns : subscriptionsWithAddOns) {
- for (final SubscriptionBase subscriptionBase : subscriptionWithAddOns.getSubscriptionBaseList()) {
- final Entitlement entitlement = new DefaultEntitlement(subscriptionWithAddOns.getBundle(),
- subscriptionBase,
- accountEventsStreams.getSubscriptions().get(subscriptionBase.getBundleId()),
- eventsStreamBuilder,
- entitlementApi,
- pluginExecution,
- blockingStateDao,
- subscriptionBaseInternalApi,
- checker,
- notificationQueueService,
- entitlementUtils,
- dateHelper,
- clock,
- securityApi,
- internalCallContextFactory,
- internalCallContext);
- result.add(entitlement);
- }
- }
- return result;
- }
-
@Override
- public Entitlement addEntitlement(final UUID bundleId, final PlanPhaseSpecifier planPhaseSpecifier, final List<PlanPhasePriceOverride> overrides, @Nullable final LocalDate entitlementEffectiveDate, @Nullable final LocalDate billingEffectiveDate,
+ public UUID addEntitlement(final UUID bundleId, final PlanPhaseSpecifier planPhaseSpecifier, final List<PlanPhasePriceOverride> overrides, @Nullable final LocalDate entitlementEffectiveDate, @Nullable final LocalDate billingEffectiveDate,
final boolean isMigrated, final Iterable<PluginProperty> properties, final CallContext callContext) throws EntitlementApiException {
-
-
logCreateEntitlement(log, bundleId, planPhaseSpecifier, overrides, entitlementEffectiveDate, billingEffectiveDate);
final EntitlementSpecifier entitlementSpecifier = new DefaultEntitlementSpecifier(planPhaseSpecifier, overrides);
@@ -283,9 +259,9 @@ public class DefaultEntitlementApi extends DefaultEntitlementApiBase implements
properties,
callContext);
- final WithEntitlementPlugin<Entitlement> addEntitlementWithPlugin = new WithEntitlementPlugin<Entitlement>() {
+ final WithEntitlementPlugin<UUID> addEntitlementWithPlugin = new WithEntitlementPlugin<UUID>() {
@Override
- public Entitlement doCall(final EntitlementApi entitlementApi, final EntitlementContext updatedPluginContext) throws EntitlementApiException {
+ public UUID doCall(final EntitlementApi entitlementApi, final EntitlementContext updatedPluginContext) throws EntitlementApiException {
final InternalCallContext context = internalCallContextFactory.createInternalCallContext(bundleId, ObjectType.BUNDLE, callContext);
final DateTime now = clock.getUTCNow();
@@ -312,45 +288,25 @@ public class DefaultEntitlementApi extends DefaultEntitlementApiBase implements
}
try {
- final BaseEntitlementWithAddOnsSpecifier baseEntitlementWithAddOnsSpecifier = getFirstBaseEntitlementWithAddOnsSpecifier(updatedPluginContext.getBaseEntitlementWithAddOnsSpecifiers());
- final EntitlementSpecifier specifier = getFirstEntitlementSpecifier(baseEntitlementWithAddOnsSpecifier);
-
- final DateTime billingRequestedDateRaw = dateHelper.fromLocalDateAndReferenceTime(baseEntitlementWithAddOnsSpecifier.getBillingEffectiveDate(), now, context);
-
- DateTime billingRequestedDate = billingRequestedDateRaw;
- if (!isStandalone) {
- final DateTime baseSubscriptionStartDate = eventsStreamForBaseSubscription.getSubscriptionBase().getStartDate();
- billingRequestedDate = billingRequestedDateRaw.isBefore(baseSubscriptionStartDate) ? baseSubscriptionStartDate : billingRequestedDateRaw;
- }
-
- final SubscriptionBaseBundle baseBundle = subscriptionBaseInternalApi.getBundleFromId(bundleId, context);
- final SubscriptionBase subscription = subscriptionBaseInternalApi.createSubscription(baseBundle,
- eventsStreamForBaseSubscription == null ? null : eventsStreamForBaseSubscription.getSubscriptionBase(),
- specifier.getPlanPhaseSpecifier(),
- specifier.getOverrides(),
- billingRequestedDate,
- isMigrated,
- context);
-
- final BlockingState newBlockingState = new DefaultBlockingState(subscription.getId(), BlockingStateType.SUBSCRIPTION, DefaultEntitlementApi.ENT_STATE_START, EntitlementService.ENTITLEMENT_SERVICE_NAME, false, false, false, entitlementRequestedDate);
- entitlementUtils.setBlockingStatesAndPostBlockingTransitionEvent(ImmutableList.<BlockingState>of(newBlockingState), subscription.getBundleId(), context);
-
- return new DefaultEntitlement(baseBundle,
- subscription,
- subscriptionsByBundle,
- eventsStreamBuilder,
- entitlementApi,
- pluginExecution,
- blockingStateDao,
- subscriptionBaseInternalApi,
- checker,
- notificationQueueService,
- entitlementUtils,
- dateHelper,
- clock,
- securityApi,
- internalCallContextFactory,
- context);
+ final BaseEntitlementWithAddOnsSpecifier baseEntitlementWithAddOnsSpecifierAfterPlugins = getFirstBaseEntitlementWithAddOnsSpecifier(updatedPluginContext.getBaseEntitlementWithAddOnsSpecifiers());
+ final DateTime billingEffectiveDateTime = (baseEntitlementWithAddOnsSpecifierAfterPlugins.getBillingEffectiveDate() != null) ?
+ context.toUTCDateTime(baseEntitlementWithAddOnsSpecifierAfterPlugins.getBillingEffectiveDate()) : null;
+ final SubscriptionBaseWithAddOnsSpecifier subscriptionBaseWithAddOnsSpecifier = new SubscriptionBaseWithAddOnsSpecifier(baseEntitlementWithAddOnsSpecifierAfterPlugins.getBundleId(),
+ baseEntitlementWithAddOnsSpecifierAfterPlugins.getExternalKey(),
+ baseEntitlementWithAddOnsSpecifierAfterPlugins.getEntitlementSpecifier(),
+ billingEffectiveDateTime,
+ baseEntitlementWithAddOnsSpecifierAfterPlugins.isMigrated());
+
+ final List<SubscriptionBaseWithAddOns> subscriptionsWithAddOns = subscriptionBaseInternalApi.createBaseSubscriptionsWithAddOns(ImmutableList.<SubscriptionBaseWithAddOnsSpecifier>of(subscriptionBaseWithAddOnsSpecifier),
+ false,
+ context);
+ final SubscriptionBaseWithAddOns subscriptionBaseWithAddOns = subscriptionsWithAddOns.get(0);
+ final UUID subscriptionId = subscriptionBaseWithAddOns.getSubscriptionBaseList().get(0).getId();
+
+ final BlockingState newBlockingState = new DefaultBlockingState(subscriptionId, BlockingStateType.SUBSCRIPTION, DefaultEntitlementApi.ENT_STATE_START, EntitlementService.ENTITLEMENT_SERVICE_NAME, false, false, false, entitlementRequestedDate);
+ entitlementUtils.setBlockingStatesAndPostBlockingTransitionEvent(ImmutableList.<BlockingState>of(newBlockingState), subscriptionBaseWithAddOns.getBundle().getId(), context);
+
+ return subscriptionId;
} catch (final SubscriptionBaseApiException e) {
throw new EntitlementApiException(e);
}
@@ -377,10 +333,9 @@ public class DefaultEntitlementApi extends DefaultEntitlementApiBase implements
public List<EntitlementAOStatusDryRun> getDryRunStatusForChange(final UUID bundleId, final String targetProductName, @Nullable final LocalDate effectiveDate, final TenantContext context) throws EntitlementApiException {
final InternalTenantContext internalContext = internalCallContextFactory.createInternalTenantContext(bundleId, ObjectType.BUNDLE, context);
try {
- final SubscriptionBaseBundle bundle = subscriptionBaseInternalApi.getBundleFromId(bundleId, internalContext);
final SubscriptionBase baseSubscription = subscriptionBaseInternalApi.getBaseSubscription(bundleId, internalContext);
-
- final InternalTenantContext contextWithValidAccountRecordId = internalCallContextFactory.createInternalTenantContext(bundle.getAccountId(), context);
+ final UUID accountId = subscriptionBaseInternalApi.getAccountIdFromBundleId(bundleId, internalContext);
+ final InternalTenantContext contextWithValidAccountRecordId = internalCallContextFactory.createInternalTenantContext(accountId, context);
final DateTime now = clock.getUTCNow();
final DateTime requestedDate = dateHelper.fromLocalDateAndReferenceTime(effectiveDate, now, contextWithValidAccountRecordId);
return subscriptionBaseInternalApi.getDryRunChangePlanStatus(baseSubscription.getId(), targetProductName, requestedDate, contextWithValidAccountRecordId);
@@ -400,7 +355,7 @@ public class DefaultEntitlementApi extends DefaultEntitlementApiBase implements
final InternalTenantContext internalContext = internalCallContextFactory.createInternalTenantContext(bundleId, ObjectType.BUNDLE, tenantContext);
final UUID accountId;
try {
- accountId = subscriptionBaseInternalApi.getBundleFromId(bundleId, internalContext).getAccountId();
+ accountId = subscriptionBaseInternalApi.getAccountIdFromBundleId(bundleId, internalContext);
} catch (final SubscriptionBaseApiException e) {
throw new EntitlementApiException(e);
}
@@ -509,12 +464,12 @@ public class DefaultEntitlementApi extends DefaultEntitlementApiBase implements
try {
final UUID activeSubscriptionIdForKey = entitlementUtils.getFirstActiveSubscriptionIdForKeyOrNull(externalKey, contextWithSourceAccountRecordId);
- final SubscriptionBase baseSubscription = activeSubscriptionIdForKey != null ?
- subscriptionBaseInternalApi.getSubscriptionFromId(activeSubscriptionIdForKey, contextWithSourceAccountRecordId) : null;
- final SubscriptionBaseBundle baseBundle = baseSubscription != null ?
- subscriptionBaseInternalApi.getBundleFromId(baseSubscription.getBundleId(), contextWithSourceAccountRecordId) : null;
+ final UUID bundleId = activeSubscriptionIdForKey != null ?
+ subscriptionBaseInternalApi.getBundleIdFromSubscriptionId(activeSubscriptionIdForKey, contextWithSourceAccountRecordId) : null;
+ final UUID baseBundleAccountId = bundleId != null ?
+ subscriptionBaseInternalApi.getAccountIdFromBundleId(bundleId, contextWithSourceAccountRecordId) : null;
- if (baseBundle == null || !baseBundle.getAccountId().equals(sourceAccountId)) {
+ if (baseBundleAccountId == null || !baseBundleAccountId.equals(sourceAccountId)) {
throw new EntitlementApiException(new SubscriptionBaseApiException(ErrorCode.SUB_GET_INVALID_BUNDLE_KEY, externalKey));
}
@@ -529,7 +484,7 @@ public class DefaultEntitlementApi extends DefaultEntitlementApiBase implements
// Block all associated subscriptions - TODO Do we want to block the bundle as well (this will add an extra STOP_ENTITLEMENT event in the bundle timeline stream)?
// Note that there is no un-transfer at the moment, so we effectively add a blocking state on disk for all subscriptions
- for (final SubscriptionBase subscriptionBase : subscriptionBaseInternalApi.getSubscriptionsForBundle(baseBundle.getId(), null, contextWithSourceAccountRecordId)) {
+ for (final SubscriptionBase subscriptionBase : subscriptionBaseInternalApi.getSubscriptionsForBundle(bundleId, null, contextWithSourceAccountRecordId)) {
final BlockingState blockingState = new DefaultBlockingState(subscriptionBase.getId(), BlockingStateType.SUBSCRIPTION, DefaultEntitlementApi.ENT_STATE_CANCELLED, EntitlementService.ENTITLEMENT_SERVICE_NAME, true, true, false, requestedDate);
blockingStates.put(blockingState, subscriptionBase.getBundleId());
}
diff --git a/entitlement/src/main/java/org/killbill/billing/entitlement/api/DefaultSubscriptionApi.java b/entitlement/src/main/java/org/killbill/billing/entitlement/api/DefaultSubscriptionApi.java
index 7316ff1..a9691ee 100644
--- a/entitlement/src/main/java/org/killbill/billing/entitlement/api/DefaultSubscriptionApi.java
+++ b/entitlement/src/main/java/org/killbill/billing/entitlement/api/DefaultSubscriptionApi.java
@@ -195,8 +195,8 @@ public class DefaultSubscriptionApi implements SubscriptionApi {
}
final InternalTenantContext internalContextWithAccountRecordId = internalCallContextFactory.createInternalTenantContext(activeSubscriptionIdForKey, ObjectType.SUBSCRIPTION, context);
- final SubscriptionBase subscriptionBase = subscriptionBaseInternalApi.getSubscriptionFromId(activeSubscriptionIdForKey, internalContextWithAccountRecordId);
- return getSubscriptionBundle(subscriptionBase.getBundleId(), context);
+ final UUID bundleId = subscriptionBaseInternalApi.getBundleIdFromSubscriptionId(activeSubscriptionIdForKey, internalContextWithAccountRecordId);
+ return getSubscriptionBundle(bundleId, context);
} catch (final SubscriptionBaseApiException e) {
throw new SubscriptionApiException(e);
}
@@ -276,11 +276,10 @@ public class DefaultSubscriptionApi implements SubscriptionApi {
final InternalCallContext internalCallContext = internalCallContextFactory.createInternalCallContext(bundleId, ObjectType.BUNDLE, callContext);
- final SubscriptionBaseBundle bundle;
final ImmutableAccountData account;
try {
- bundle = subscriptionBaseInternalApi.getBundleFromId(bundleId, internalCallContext);
- account = accountApi.getImmutableAccountDataById(bundle.getAccountId(), internalCallContext);
+ final UUID accountId = subscriptionBaseInternalApi.getAccountIdFromBundleId(bundleId, internalCallContext);
+ account = accountApi.getImmutableAccountDataById(accountId, internalCallContext);
} catch (final SubscriptionBaseApiException e) {
throw new EntitlementApiException(e);
} catch (AccountApiException e) {
@@ -299,7 +298,7 @@ public class DefaultSubscriptionApi implements SubscriptionApi {
final List<BaseEntitlementWithAddOnsSpecifier> baseEntitlementWithAddOnsSpecifierList = new ArrayList<BaseEntitlementWithAddOnsSpecifier>();
baseEntitlementWithAddOnsSpecifierList.add(baseEntitlementWithAddOnsSpecifier);
final EntitlementContext pluginContext = new DefaultEntitlementContext(OperationType.UPDATE_BUNDLE_EXTERNAL_KEY,
- bundle.getAccountId(),
+ account.getId(),
null,
baseEntitlementWithAddOnsSpecifierList,
null,
diff --git a/entitlement/src/main/java/org/killbill/billing/entitlement/block/DefaultBlockingChecker.java b/entitlement/src/main/java/org/killbill/billing/entitlement/block/DefaultBlockingChecker.java
index d793106..20f76a8 100644
--- a/entitlement/src/main/java/org/killbill/billing/entitlement/block/DefaultBlockingChecker.java
+++ b/entitlement/src/main/java/org/killbill/billing/entitlement/block/DefaultBlockingChecker.java
@@ -136,44 +136,41 @@ public class DefaultBlockingChecker implements BlockingChecker {
}
private DefaultBlockingAggregator getBlockedStateSubscriptionId(final UUID subscriptionId, final DateTime upToDate, final InternalTenantContext context) throws BlockingApiException {
- final SubscriptionBase subscription;
try {
- subscription = subscriptionApi.getSubscriptionFromId(subscriptionId, context);
- return getBlockedStateSubscription(subscription, upToDate, context);
+ final UUID bundleId = subscriptionApi.getBundleIdFromSubscriptionId(subscriptionId, context);
+ return getBlockedStateSubscription(bundleId, subscriptionId, upToDate, context);
} catch (final SubscriptionBaseApiException e) {
throw new BlockingApiException(e, ErrorCode.fromCode(e.getCode()));
}
}
- private DefaultBlockingAggregator getBlockedStateSubscription(final SubscriptionBase subscription, final DateTime upToDate, final InternalTenantContext context) throws BlockingApiException {
+ private DefaultBlockingAggregator getBlockedStateSubscription(@Nullable final UUID bundleId, @Nullable final UUID subscriptionId, final DateTime upToDate, final InternalTenantContext context) throws BlockingApiException {
final DefaultBlockingAggregator result = new DefaultBlockingAggregator();
- if (subscription != null) {
- final DefaultBlockingAggregator subscriptionState = getBlockedStateForId(subscription.getId(), BlockingStateType.SUBSCRIPTION, upToDate, context);
+ if (subscriptionId != null) {
+ final DefaultBlockingAggregator subscriptionState = getBlockedStateForId(subscriptionId, BlockingStateType.SUBSCRIPTION, upToDate, context);
if (subscriptionState != null) {
result.or(subscriptionState);
}
- if (subscription.getBundleId() != null) {
+ if (bundleId != null) {
// Recursive call to also fetch account state
- result.or(getBlockedStateBundleId(subscription.getBundleId(), upToDate, context));
+ result.or(getBlockedStateBundleId(bundleId, upToDate, context));
}
}
return result;
}
private DefaultBlockingAggregator getBlockedStateBundleId(final UUID bundleId, final DateTime upToDate, final InternalTenantContext context) throws BlockingApiException {
-
- final SubscriptionBaseBundle bundle;
try {
- bundle = subscriptionApi.getBundleFromId(bundleId, context);
- return getBlockedStateBundle(bundle, upToDate, context);
+ final UUID accountId = subscriptionApi.getAccountIdFromBundleId(bundleId, context);
+ return getBlockedStateBundle(accountId, bundleId, upToDate, context);
} catch (final SubscriptionBaseApiException e) {
throw new BlockingApiException(e, ErrorCode.fromCode(e.getCode()));
}
}
- private DefaultBlockingAggregator getBlockedStateBundle(final SubscriptionBaseBundle bundle, final DateTime upToDate, final InternalTenantContext context) {
- final DefaultBlockingAggregator result = getBlockedStateAccountId(bundle.getAccountId(), upToDate, context);
- final DefaultBlockingAggregator bundleState = getBlockedStateForId(bundle.getId(), BlockingStateType.SUBSCRIPTION_BUNDLE, upToDate, context);
+ private DefaultBlockingAggregator getBlockedStateBundle(final UUID accountId, final UUID bundleId, final DateTime upToDate, final InternalTenantContext context) {
+ final DefaultBlockingAggregator result = getBlockedStateAccountId(accountId, upToDate, context);
+ final DefaultBlockingAggregator bundleState = getBlockedStateForId(bundleId, BlockingStateType.SUBSCRIPTION_BUNDLE, upToDate, context);
if (bundleState != null) {
result.or(bundleState);
}
@@ -220,9 +217,9 @@ public class DefaultBlockingChecker implements BlockingChecker {
@Override
public void checkBlockedChange(final Blockable blockable, final DateTime upToDate, final InternalTenantContext context) throws BlockingApiException {
- if (blockable instanceof SubscriptionBase && getBlockedStateSubscription((SubscriptionBase) blockable, upToDate, context).isBlockChange()) {
+ if (blockable instanceof SubscriptionBase && getBlockedStateSubscription(((SubscriptionBase) blockable).getBundleId(), blockable.getId(), upToDate, context).isBlockChange()) {
throw new BlockingApiException(ErrorCode.BLOCK_BLOCKED_ACTION, ACTION_CHANGE, TYPE_SUBSCRIPTION, blockable.getId().toString());
- } else if (blockable instanceof SubscriptionBaseBundle && getBlockedStateBundle((SubscriptionBaseBundle) blockable, upToDate, context).isBlockChange()) {
+ } else if (blockable instanceof SubscriptionBaseBundle && getBlockedStateBundle(((SubscriptionBaseBundle) blockable).getAccountId(), blockable.getId(), upToDate, context).isBlockChange()) {
throw new BlockingApiException(ErrorCode.BLOCK_BLOCKED_ACTION, ACTION_CHANGE, TYPE_BUNDLE, blockable.getId().toString());
} else if (blockable instanceof Account && getBlockedStateAccount((Account) blockable, upToDate, context).isBlockChange()) {
throw new BlockingApiException(ErrorCode.BLOCK_BLOCKED_ACTION, ACTION_CHANGE, TYPE_ACCOUNT, blockable.getId().toString());
@@ -231,9 +228,9 @@ public class DefaultBlockingChecker implements BlockingChecker {
@Override
public void checkBlockedEntitlement(final Blockable blockable, final DateTime upToDate, final InternalTenantContext context) throws BlockingApiException {
- if (blockable instanceof SubscriptionBase && getBlockedStateSubscription((SubscriptionBase) blockable, upToDate, context).isBlockEntitlement()) {
+ if (blockable instanceof SubscriptionBase && getBlockedStateSubscription(((SubscriptionBase) blockable).getBundleId(), blockable.getId(), upToDate, context).isBlockEntitlement()) {
throw new BlockingApiException(ErrorCode.BLOCK_BLOCKED_ACTION, ACTION_ENTITLEMENT, TYPE_SUBSCRIPTION, blockable.getId().toString());
- } else if (blockable instanceof SubscriptionBaseBundle && getBlockedStateBundle((SubscriptionBaseBundle) blockable, upToDate, context).isBlockEntitlement()) {
+ } else if (blockable instanceof SubscriptionBaseBundle && getBlockedStateBundle(((SubscriptionBaseBundle) blockable).getAccountId(), blockable.getId(), upToDate, context).isBlockEntitlement()) {
throw new BlockingApiException(ErrorCode.BLOCK_BLOCKED_ACTION, ACTION_ENTITLEMENT, TYPE_BUNDLE, blockable.getId().toString());
} else if (blockable instanceof Account && getBlockedStateAccount((Account) blockable, upToDate, context).isBlockEntitlement()) {
throw new BlockingApiException(ErrorCode.BLOCK_BLOCKED_ACTION, ACTION_ENTITLEMENT, TYPE_ACCOUNT, blockable.getId().toString());
@@ -242,9 +239,9 @@ public class DefaultBlockingChecker implements BlockingChecker {
@Override
public void checkBlockedBilling(final Blockable blockable, final DateTime upToDate, final InternalTenantContext context) throws BlockingApiException {
- if (blockable instanceof SubscriptionBase && getBlockedStateSubscription((SubscriptionBase) blockable, upToDate, context).isBlockBilling()) {
+ if (blockable instanceof SubscriptionBase && getBlockedStateSubscription(((SubscriptionBase) blockable).getBundleId(), blockable.getId(), upToDate, context).isBlockBilling()) {
throw new BlockingApiException(ErrorCode.BLOCK_BLOCKED_ACTION, ACTION_BILLING, TYPE_SUBSCRIPTION, blockable.getId().toString());
- } else if (blockable instanceof SubscriptionBaseBundle && getBlockedStateBundle((SubscriptionBaseBundle) blockable, upToDate, context).isBlockBilling()) {
+ } else if (blockable instanceof SubscriptionBaseBundle && getBlockedStateBundle(((SubscriptionBaseBundle) blockable).getAccountId(), blockable.getId(), upToDate, context).isBlockBilling()) {
throw new BlockingApiException(ErrorCode.BLOCK_BLOCKED_ACTION, ACTION_BILLING, TYPE_BUNDLE, blockable.getId().toString());
} else if (blockable instanceof Account && getBlockedStateAccount((Account) blockable, upToDate, context).isBlockBilling()) {
throw new BlockingApiException(ErrorCode.BLOCK_BLOCKED_ACTION, ACTION_BILLING, TYPE_ACCOUNT, blockable.getId().toString());
diff --git a/entitlement/src/main/java/org/killbill/billing/entitlement/dao/OptimizedProxyBlockingStateDao.java b/entitlement/src/main/java/org/killbill/billing/entitlement/dao/OptimizedProxyBlockingStateDao.java
index 7df7117..9e9ba63 100644
--- a/entitlement/src/main/java/org/killbill/billing/entitlement/dao/OptimizedProxyBlockingStateDao.java
+++ b/entitlement/src/main/java/org/killbill/billing/entitlement/dao/OptimizedProxyBlockingStateDao.java
@@ -69,6 +69,7 @@ public class OptimizedProxyBlockingStateDao extends ProxyBlockingStateDao {
* @param baseSubscription base subscription (ProductCategory.BASE) associated with that bundle
* @param subscription subscription for which to build blocking states
* @param allSubscriptionsForBundle all subscriptions associated with that bundle
+ * @param accountBCD account BCD
* @param catalog full Catalog
* @param context call context
* @return blocking states for that subscription
@@ -81,6 +82,7 @@ public class OptimizedProxyBlockingStateDao extends ProxyBlockingStateDao {
@Nullable final SubscriptionBase baseSubscription,
final SubscriptionBase subscription,
final Collection<SubscriptionBase> allSubscriptionsForBundle,
+ final int accountBCD,
final Catalog catalog,
final InternalTenantContext context) throws EntitlementApiException {
// blockable id points to a subscription, but make sure it's an add-on
@@ -95,6 +97,7 @@ public class OptimizedProxyBlockingStateDao extends ProxyBlockingStateDao {
bundle,
baseSubscription,
allSubscriptionsForBundle,
+ accountBCD,
catalog,
context));
diff --git a/entitlement/src/main/java/org/killbill/billing/entitlement/engine/core/DefaultEventsStream.java b/entitlement/src/main/java/org/killbill/billing/entitlement/engine/core/DefaultEventsStream.java
index 667b114..5ff2339 100644
--- a/entitlement/src/main/java/org/killbill/billing/entitlement/engine/core/DefaultEventsStream.java
+++ b/entitlement/src/main/java/org/killbill/billing/entitlement/engine/core/DefaultEventsStream.java
@@ -85,9 +85,12 @@ public class DefaultEventsStream implements EventsStream {
private BlockingState entitlementCancelEvent;
private EntitlementState entitlementState;
- public DefaultEventsStream(final ImmutableAccountData account, final SubscriptionBaseBundle bundle,
- final Collection<BlockingState> blockingStates, final BlockingChecker blockingChecker,
- @Nullable final SubscriptionBase baseSubscription, final SubscriptionBase subscription,
+ public DefaultEventsStream(final ImmutableAccountData account,
+ final SubscriptionBaseBundle bundle,
+ final Collection<BlockingState> blockingStates,
+ final BlockingChecker blockingChecker,
+ @Nullable final SubscriptionBase baseSubscription,
+ final SubscriptionBase subscription,
final Collection<SubscriptionBase> allSubscriptionsForBundle,
final int defaultBillCycleDayLocal,
final InternalTenantContext contextWithValidAccountRecordId, final DateTime utcNow) {
diff --git a/entitlement/src/main/java/org/killbill/billing/entitlement/engine/core/EntitlementUtils.java b/entitlement/src/main/java/org/killbill/billing/entitlement/engine/core/EntitlementUtils.java
index fd44b4d..5307695 100644
--- a/entitlement/src/main/java/org/killbill/billing/entitlement/engine/core/EntitlementUtils.java
+++ b/entitlement/src/main/java/org/killbill/billing/entitlement/engine/core/EntitlementUtils.java
@@ -78,7 +78,7 @@ public class EntitlementUtils {
// We only need the bundle id in case of subscriptions (at the account level, we don't need it and at the bundle level, we already have it)
if (state.getType() == BlockingStateType.SUBSCRIPTION) {
try {
- bundleId = subscriptionBaseInternalApi.getSubscriptionFromId(state.getBlockedId(), context).getBundleId();
+ bundleId = subscriptionBaseInternalApi.getBundleIdFromSubscriptionId(state.getBlockedId(), context);
} catch (final SubscriptionBaseApiException e) {
throw new RuntimeException(e);
}
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 63281e8..637ad39 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
@@ -149,8 +149,10 @@ public class EventsStreamBuilder {
public AccountEventsStreams buildForAccount(final Map<UUID, List<SubscriptionBase>> subscriptions, final Catalog catalog, final InternalTenantContext internalTenantContext) throws EntitlementApiException {
// Retrieve the account
final ImmutableAccountData account;
+ final int accountBCD;
try {
account = accountInternalApi.getImmutableAccountDataByRecordId(internalTenantContext.getAccountRecordId(), internalTenantContext);
+ accountBCD = accountInternalApi.getBCD(account.getId(), internalTenantContext);
} catch (final AccountApiException e) {
throw new EntitlementApiException(e);
}
@@ -227,6 +229,7 @@ public class EventsStreamBuilder {
baseSubscription,
subscription,
allSubscriptionsForBundle,
+ accountBCD,
catalog,
internalTenantContext);
@@ -244,6 +247,7 @@ public class EventsStreamBuilder {
subscription,
allSubscriptionsForBundle,
blockingStates,
+ accountBCD,
bcdCache,
catalog,
internalTenantContext);
@@ -269,7 +273,25 @@ public class EventsStreamBuilder {
return buildForEntitlement(bundle, subscription, subscriptionsForBundle, internalTenantContext);
}
- public EventsStream buildForEntitlement(final SubscriptionBaseBundle bundle, final SubscriptionBase subscription, final Collection<SubscriptionBase> allSubscriptionsForBundle, final InternalTenantContext internalTenantContext) throws EntitlementApiException {
+ public EventsStream buildForEntitlement(final SubscriptionBaseBundle bundle,
+ final SubscriptionBase subscription,
+ final Collection<SubscriptionBase> allSubscriptionsForBundle,
+ final InternalTenantContext internalTenantContext) throws EntitlementApiException {
+ final int accountBCD;
+ try {
+ accountBCD = accountInternalApi.getBCD(bundle.getAccountId(), internalTenantContext);
+ } catch (final AccountApiException e) {
+ throw new EntitlementApiException(e);
+ }
+
+ return buildForEntitlement(bundle, subscription, allSubscriptionsForBundle, accountBCD, internalTenantContext);
+ }
+
+ public EventsStream buildForEntitlement(final SubscriptionBaseBundle bundle,
+ final SubscriptionBase subscription,
+ final Collection<SubscriptionBase> allSubscriptionsForBundle,
+ final int accountBCD,
+ final InternalTenantContext internalTenantContext) throws EntitlementApiException {
final SubscriptionBase baseSubscription = findBaseSubscription(allSubscriptionsForBundle);
final ImmutableAccountData account;
@@ -285,7 +307,7 @@ public class EventsStreamBuilder {
final List<BlockingState> blockingStatesForAccount = defaultBlockingStateDao.getBlockingAllForAccountRecordId(catalog, internalTenantContext);
final Map<UUID, Integer> bcdCache = new HashMap<UUID, Integer>();
- return buildForEntitlement(blockingStatesForAccount, account, bundle, baseSubscription, subscription, allSubscriptionsForBundle, bcdCache, catalog, internalTenantContext);
+ return buildForEntitlement(blockingStatesForAccount, account, bundle, baseSubscription, subscription, allSubscriptionsForBundle, accountBCD, bcdCache, catalog, internalTenantContext);
}
// Special signature for OptimizedProxyBlockingStateDao to save some DAO calls
@@ -294,10 +316,11 @@ public class EventsStreamBuilder {
final SubscriptionBaseBundle bundle,
final SubscriptionBase baseSubscription,
final Collection<SubscriptionBase> allSubscriptionsForBundle,
+ final int accountBCD,
final Catalog catalog,
final InternalTenantContext internalTenantContext) throws EntitlementApiException {
final Map<UUID, Integer> bcdCache = new HashMap<UUID, Integer>();
- return buildForEntitlement(blockingStatesForAccount, account, bundle, baseSubscription, baseSubscription, allSubscriptionsForBundle, bcdCache, catalog, internalTenantContext);
+ return buildForEntitlement(blockingStatesForAccount, account, bundle, baseSubscription, baseSubscription, allSubscriptionsForBundle, accountBCD, bcdCache, catalog, internalTenantContext);
}
private EventsStream buildForEntitlement(final Collection<BlockingState> blockingStatesForAccount,
@@ -306,6 +329,7 @@ public class EventsStreamBuilder {
@Nullable final SubscriptionBase baseSubscription,
final SubscriptionBase subscription,
final Collection<SubscriptionBase> allSubscriptionsForBundle,
+ final int accountBCD,
final Map<UUID, Integer> bcdCache,
final Catalog catalog,
final InternalTenantContext internalTenantContext) throws EntitlementApiException {
@@ -350,6 +374,7 @@ public class EventsStreamBuilder {
baseSubscription,
subscription,
allSubscriptionsForBundle,
+ accountBCD,
catalog,
internalTenantContext);
}
@@ -360,7 +385,7 @@ public class EventsStreamBuilder {
blockingStateSet.addAll(subscriptionBlockingStates);
final List<BlockingState> blockingStates = ProxyBlockingStateDao.sortedCopy(blockingStateSet);
- return buildForEntitlement(account, bundle, baseSubscription, subscription, allSubscriptionsForBundle, blockingStates, bcdCache, catalog, internalTenantContext);
+ return buildForEntitlement(account, bundle, baseSubscription, subscription, allSubscriptionsForBundle, blockingStates, accountBCD, bcdCache, catalog, internalTenantContext);
}
private EventsStream buildForEntitlement(final ImmutableAccountData account,
@@ -369,12 +394,12 @@ public class EventsStreamBuilder {
final SubscriptionBase subscription,
final Collection<SubscriptionBase> allSubscriptionsForBundle,
final Collection<BlockingState> blockingStates,
+ final int accountBCD,
final Map<UUID, Integer> bcdCache,
final Catalog catalog,
final InternalTenantContext internalTenantContext) throws EntitlementApiException {
try {
- final int accountBCD = accountInternalApi.getBCD(account.getId(), internalTenantContext);
final int defaultAlignmentDay = subscriptionInternalApi.getDefaultBillCycleDayLocal(bcdCache,
subscription,
baseSubscription,
@@ -394,8 +419,6 @@ public class EventsStreamBuilder {
clock.getUTCNow());
} catch (final SubscriptionBaseApiException e) {
throw new EntitlementApiException(e);
- } catch (final AccountApiException e) {
- throw new EntitlementApiException(e);
}
}
diff --git a/entitlement/src/test/java/org/killbill/billing/entitlement/api/TestDefaultEntitlement.java b/entitlement/src/test/java/org/killbill/billing/entitlement/api/TestDefaultEntitlement.java
index 937f095..5a472f3 100644
--- a/entitlement/src/test/java/org/killbill/billing/entitlement/api/TestDefaultEntitlement.java
+++ b/entitlement/src/test/java/org/killbill/billing/entitlement/api/TestDefaultEntitlement.java
@@ -18,6 +18,8 @@
package org.killbill.billing.entitlement.api;
+import java.util.UUID;
+
import org.joda.time.DateTime;
import org.joda.time.LocalDate;
import org.killbill.billing.ErrorCode;
@@ -27,7 +29,6 @@ import org.killbill.billing.api.TestApiListener.NextEvent;
import org.killbill.billing.catalog.api.BillingPeriod;
import org.killbill.billing.catalog.api.PlanPhasePriceOverride;
import org.killbill.billing.catalog.api.PlanPhaseSpecifier;
-import org.killbill.billing.catalog.api.PlanSpecifier;
import org.killbill.billing.catalog.api.PriceListSet;
import org.killbill.billing.entitlement.EntitlementTestSuiteWithEmbeddedDB;
import org.killbill.billing.entitlement.api.Entitlement.EntitlementActionPolicy;
@@ -55,8 +56,9 @@ public class TestDefaultEntitlement extends EntitlementTestSuiteWithEmbeddedDB {
// Create entitlement and check each field
testListener.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK);
- final Entitlement entitlement = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
+ final Entitlement entitlement = entitlementApi.getEntitlementForId(entitlementId, callContext);
assertEquals(entitlement.getState(), EntitlementState.ACTIVE);
assertEquals(entitlement.getSourceType(), EntitlementSourceType.NATIVE);
@@ -83,8 +85,9 @@ public class TestDefaultEntitlement extends EntitlementTestSuiteWithEmbeddedDB {
// Create entitlement and check each field
testListener.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK);
- final Entitlement entitlement = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
+ final Entitlement entitlement = entitlementApi.getEntitlementForId(entitlementId, callContext);
assertEquals(entitlement.getState(), EntitlementState.ACTIVE);
clock.addDays(5);
@@ -116,8 +119,9 @@ public class TestDefaultEntitlement extends EntitlementTestSuiteWithEmbeddedDB {
// Create entitlement and check each field
testListener.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK);
- final Entitlement entitlement = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
+ final Entitlement entitlement = entitlementApi.getEntitlementForId(entitlementId, callContext);
assertEquals(entitlement.getState(), EntitlementState.ACTIVE);
clock.addDays(5);
@@ -149,8 +153,9 @@ public class TestDefaultEntitlement extends EntitlementTestSuiteWithEmbeddedDB {
// Create entitlement and check each field
testListener.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK);
- final Entitlement entitlement = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, null, null, false, false, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, null, null, false, false, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
+ final Entitlement entitlement = entitlementApi.getEntitlementForId(entitlementId, callContext);
assertEquals(entitlement.getState(), EntitlementState.ACTIVE);
clock.addDays(5);
@@ -182,8 +187,9 @@ public class TestDefaultEntitlement extends EntitlementTestSuiteWithEmbeddedDB {
// Create entitlement and check each field
testListener.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK);
- final Entitlement entitlement = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
+ final Entitlement entitlement = entitlementApi.getEntitlementForId(entitlementId, callContext);
testListener.pushExpectedEvents(NextEvent.CANCEL, NextEvent.BLOCK);
final Entitlement cancelledEntitlement = entitlement.cancelEntitlementWithPolicy(EntitlementActionPolicy.END_OF_TERM, ImmutableList.<PluginProperty>of(), callContext);
@@ -207,9 +213,9 @@ public class TestDefaultEntitlement extends EntitlementTestSuiteWithEmbeddedDB {
// Create entitlement and check each field
testListener.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK);
- final Entitlement entitlement = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
-
+ final Entitlement entitlement = entitlementApi.getEntitlementForId(entitlementId, callContext);
final DateTime ctd = clock.getUTCNow().plusDays(30).plusMonths(1);
testListener.pushExpectedEvent(NextEvent.PHASE);
// Go to 2013-09-08
@@ -250,8 +256,9 @@ public class TestDefaultEntitlement extends EntitlementTestSuiteWithEmbeddedDB {
// Create entitlement and check each field
testListener.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK);
- final Entitlement entitlement = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
+ final Entitlement entitlement = entitlementApi.getEntitlementForId(entitlementId, callContext);
final DateTime ctd = clock.getUTCNow().plusDays(30).plusMonths(1);
testListener.pushExpectedEvent(NextEvent.PHASE);
@@ -290,8 +297,9 @@ public class TestDefaultEntitlement extends EntitlementTestSuiteWithEmbeddedDB {
// Create entitlement and check each field
testListener.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK);
- final Entitlement entitlement = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
+ final Entitlement entitlement = entitlementApi.getEntitlementForId(entitlementId, callContext);
// Immediate change during trial
testListener.pushExpectedEvent(NextEvent.CREATE);
@@ -325,8 +333,9 @@ public class TestDefaultEntitlement extends EntitlementTestSuiteWithEmbeddedDB {
final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Shotgun", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null);
// Create entitlement and check each field
- final Entitlement entitlement = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, startDate, startDate, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, startDate, startDate, false, true, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
+ final Entitlement entitlement = entitlementApi.getEntitlementForId(entitlementId, callContext);
assertEquals(entitlement.getState(), EntitlementState.PENDING);
final PlanPhaseSpecifier spec2 = new PlanPhaseSpecifier("pistol-monthly", null);
diff --git a/entitlement/src/test/java/org/killbill/billing/entitlement/api/TestDefaultEntitlementApi.java b/entitlement/src/test/java/org/killbill/billing/entitlement/api/TestDefaultEntitlementApi.java
index a18dc97..46bb77b 100644
--- a/entitlement/src/test/java/org/killbill/billing/entitlement/api/TestDefaultEntitlementApi.java
+++ b/entitlement/src/test/java/org/killbill/billing/entitlement/api/TestDefaultEntitlementApi.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
@@ -64,15 +64,18 @@ public class TestDefaultEntitlementApi extends EntitlementTestSuiteWithEmbeddedD
// Create base entitlement (null LocalDate will map to now(), i.e. 2013-08-07T00:00:05.000Z)
testListener.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK);
final PlanPhaseSpecifier baseSpec = new PlanPhaseSpecifier("Shotgun", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null);
- final DefaultEntitlement baseEntitlement = (DefaultEntitlement) entitlementApi.createBaseEntitlement(account.getId(), baseSpec, account.getExternalKey(), null, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
+
+ final UUID baseEntitlementId = entitlementApi.createBaseEntitlement(account.getId(), baseSpec, account.getExternalKey(), null, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
+ final DefaultEntitlement baseEntitlement = (DefaultEntitlement) entitlementApi.getEntitlementForId(baseEntitlementId, callContext);
Assert.assertEquals(baseEntitlement.getSubscriptionBase().getStartDate().compareTo(account.getReferenceTime().plusSeconds(5)), 0);
// Add ADD_ON (verify date passed, i.e. initialDate, won't map to 2013-08-07T00:00:00.000Z)
testListener.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK);
final PlanPhaseSpecifier addOnSpec = new PlanPhaseSpecifier("Telescopic-Scope", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null);
- final DefaultEntitlement addOnEntitlement = (DefaultEntitlement) entitlementApi.addEntitlement(baseEntitlement.getBundleId(), addOnSpec, null, initialDate, initialDate, false, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID addOnEntitlementId = entitlementApi.addEntitlement(baseEntitlement.getBundleId(), addOnSpec, null, initialDate, initialDate, false, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
+ final DefaultEntitlement addOnEntitlement = (DefaultEntitlement) entitlementApi.getEntitlementForId(addOnEntitlementId, callContext);
Assert.assertEquals(addOnEntitlement.getSubscriptionBase().getStartDate().compareTo(baseEntitlement.getSubscriptionBase().getStartDate()), 0);
}
@@ -87,14 +90,15 @@ public class TestDefaultEntitlementApi extends EntitlementTestSuiteWithEmbeddedD
// Keep the same object for the whole test, to make sure we refresh its state before r/w calls
testListener.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK);
- final Entitlement entitlement = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
+ final Entitlement entitlement = entitlementApi.getEntitlementForId(entitlementId, callContext);
// Add ADD_ON
// Keep the same object for the whole test, to make sure we refresh its state before r/w calls
final PlanPhaseSpecifier addOnSpec = new PlanPhaseSpecifier("Telescopic-Scope", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null);
testListener.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK);
- final Entitlement addOnEntitlement = entitlementApi.addEntitlement(entitlement.getBundleId(), addOnSpec, null, initialDate, initialDate, false, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID addOnEntitlementId = entitlementApi.addEntitlement(entitlement.getBundleId(), addOnSpec, null, initialDate, initialDate, false, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
try {
entitlement.uncancelEntitlement(ImmutableList.<PluginProperty>of(), callContext);
@@ -117,6 +121,7 @@ public class TestDefaultEntitlementApi extends EntitlementTestSuiteWithEmbeddedD
Assert.assertEquals(e.getCode(), ErrorCode.SUB_CANCEL_BAD_STATE.getCode());
}
+ final Entitlement addOnEntitlement = entitlementApi.getEntitlementForId(addOnEntitlementId, callContext);
try {
addOnEntitlement.cancelEntitlementWithDateOverrideBillingPolicy(clock.getUTCToday(), BillingActionPolicy.IMMEDIATE, ImmutableList.<PluginProperty>of(), callContext);
Assert.fail("Add-On Entitlement is already cancelled");
@@ -150,8 +155,9 @@ public class TestDefaultEntitlementApi extends EntitlementTestSuiteWithEmbeddedD
// Keep the same object for the whole test, to make sure we refresh its state before r/w calls
testListener.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK);
- final Entitlement entitlement = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
+ final Entitlement entitlement = entitlementApi.getEntitlementForId(entitlementId, callContext);
testListener.pushExpectedEvent(NextEvent.PHASE);
clock.addDays(30);
@@ -183,8 +189,9 @@ public class TestDefaultEntitlementApi extends EntitlementTestSuiteWithEmbeddedD
// Create entitlement and check each field
testListener.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK);
- final Entitlement entitlement = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
+ final Entitlement entitlement = entitlementApi.getEntitlementForId(entitlementId, callContext);
assertEquals(entitlement.getAccountId(), account.getId());
assertEquals(entitlement.getExternalKey(), account.getExternalKey());
@@ -275,14 +282,16 @@ public class TestDefaultEntitlementApi extends EntitlementTestSuiteWithEmbeddedD
// Create entitlement and check each field
testListener.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK);
- final Entitlement baseEntitlement = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID baseEntitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
+ final Entitlement baseEntitlement = entitlementApi.getEntitlementForId(baseEntitlementId, callContext);
// Add ADD_ON
final PlanPhaseSpecifier spec1 = new PlanPhaseSpecifier("Telescopic-Scope", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null);
testListener.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK);
- final Entitlement telescopicEntitlement = entitlementApi.addEntitlement(baseEntitlement.getBundleId(), spec1, null, initialDate, initialDate, false, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID telescopicEntitlementId = entitlementApi.addEntitlement(baseEntitlement.getBundleId(), spec1, null, initialDate, initialDate, false, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
+ final Entitlement telescopicEntitlement = entitlementApi.getEntitlementForId(telescopicEntitlementId, callContext);
assertEquals(telescopicEntitlement.getAccountId(), account.getId());
assertEquals(telescopicEntitlement.getExternalKey(), account.getExternalKey());
@@ -314,7 +323,8 @@ public class TestDefaultEntitlementApi extends EntitlementTestSuiteWithEmbeddedD
// Create entitlement and check each field
final LocalDate startDate = initialDate.plusDays(10);
- final Entitlement baseEntitlement = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, startDate, startDate, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID baseEntitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, startDate, startDate, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final Entitlement baseEntitlement = entitlementApi.getEntitlementForId(baseEntitlementId, callContext);
// Add ADD_ON immediately. Because BASE is PENDING should fail
final PlanPhaseSpecifier spec1 = new PlanPhaseSpecifier("Telescopic-Scope", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null);
@@ -328,7 +338,8 @@ public class TestDefaultEntitlementApi extends EntitlementTestSuiteWithEmbeddedD
// Add ADD_ON with a startDate similar to BASE
- final Entitlement telescopicEntitlement = entitlementApi.addEntitlement(baseEntitlement.getBundleId(), spec1, null, startDate, startDate, false, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID telescopicEntitlementId = entitlementApi.addEntitlement(baseEntitlement.getBundleId(), spec1, null, startDate, startDate, false, ImmutableList.<PluginProperty>of(), callContext);
+ final Entitlement telescopicEntitlement = entitlementApi.getEntitlementForId(telescopicEntitlementId, callContext);
testListener.pushExpectedEvents(NextEvent.CREATE, NextEvent.CREATE, NextEvent.BLOCK, NextEvent.BLOCK);
clock.addDays(10);
@@ -365,15 +376,17 @@ public class TestDefaultEntitlementApi extends EntitlementTestSuiteWithEmbeddedD
// Create entitlement and check each field
testListener.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK);
- final Entitlement baseEntitlement = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID baseEntitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
+ final Entitlement baseEntitlement = entitlementApi.getEntitlementForId(baseEntitlementId, callContext);
clock.addDays(1);
final LocalDate effectiveDateSpec1 = new LocalDate(clock.getUTCNow(), account.getTimeZone());
final PlanPhaseSpecifier spec1 = new PlanPhaseSpecifier("Telescopic-Scope", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null);
testListener.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK);
- final Entitlement telescopicEntitlement = entitlementApi.addEntitlement(baseEntitlement.getBundleId(), spec1, null, effectiveDateSpec1, effectiveDateSpec1, false, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID telescopicEntitlementId = entitlementApi.addEntitlement(baseEntitlement.getBundleId(), spec1, null, effectiveDateSpec1, effectiveDateSpec1, false, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
+ final Entitlement telescopicEntitlement = entitlementApi.getEntitlementForId(telescopicEntitlementId, callContext);
// Block all entitlement in the bundle
clock.addDays(5);
@@ -440,8 +453,9 @@ public class TestDefaultEntitlementApi extends EntitlementTestSuiteWithEmbeddedD
// Create entitlement
testListener.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK);
final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Shotgun", BillingPeriod.ANNUAL, PriceListSet.DEFAULT_PRICELIST_NAME, null);
- final Entitlement baseEntitlement = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID baseEntitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
+ final Entitlement baseEntitlement = entitlementApi.getEntitlementForId(baseEntitlementId, callContext);
// Get the phase event out of the way
testListener.pushExpectedEvents(NextEvent.PHASE);
@@ -531,8 +545,9 @@ public class TestDefaultEntitlementApi extends EntitlementTestSuiteWithEmbeddedD
// Create entitlement (with migrated flag so we can check later that transferred subscription is in right status)
testListener.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK);
- final Entitlement baseEntitlement = entitlementApi.createBaseEntitlement(accountSrc.getId(), spec, accountSrc.getExternalKey(), null, null, null, true, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID baseEntitlementId = entitlementApi.createBaseEntitlement(accountSrc.getId(), spec, accountSrc.getExternalKey(), null, null, null, true, true, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
+ final Entitlement baseEntitlement = entitlementApi.getEntitlementForId(baseEntitlementId, callContext);
assertEquals(baseEntitlement.getSourceType(), EntitlementSourceType.MIGRATED);
// Again to make sure this flag is correctly wrote/set
assertEquals(entitlementApi.getEntitlementForId(baseEntitlement.getId(), callContext).getSourceType(), EntitlementSourceType.MIGRATED);
@@ -578,8 +593,9 @@ public class TestDefaultEntitlementApi extends EntitlementTestSuiteWithEmbeddedD
// Keep the same object for the whole test, to make sure we refresh its state before r/w calls
testListener.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK, NextEvent.PHASE);
- final Entitlement entitlement = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, initialDate, initialDate, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, initialDate, initialDate, false, true, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
+ final Entitlement entitlement = entitlementApi.getEntitlementForId(entitlementId, callContext);
assertEquals(entitlement.getAccountId(), account.getId());
assertEquals(entitlement.getExternalKey(), account.getExternalKey());
@@ -624,8 +640,9 @@ public class TestDefaultEntitlementApi extends EntitlementTestSuiteWithEmbeddedD
final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Shotgun", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null);
- Entitlement entitlement = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, entitlementDate, billingDate, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, entitlementDate, billingDate, false, true, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
+ Entitlement entitlement = entitlementApi.getEntitlementForId(entitlementId, callContext);
assertEquals(entitlement.getState(), EntitlementState.PENDING);
assertEquals(entitlement.getEffectiveStartDate(), entitlementDate);
@@ -681,8 +698,9 @@ public class TestDefaultEntitlementApi extends EntitlementTestSuiteWithEmbeddedD
final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Shotgun", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null);
testListener.pushExpectedEvents(NextEvent.CREATE);
- final Entitlement entitlement = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, entitlementDate, billingDate, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, entitlementDate, billingDate, false, true, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
+ final Entitlement entitlement = entitlementApi.getEntitlementForId(entitlementId, callContext);
assertEquals(entitlement.getState(), EntitlementState.PENDING);
assertEquals(entitlement.getEffectiveStartDate(), entitlementDate);
@@ -708,8 +726,9 @@ public class TestDefaultEntitlementApi extends EntitlementTestSuiteWithEmbeddedD
final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Shotgun", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null);
testListener.pushExpectedEvents(NextEvent.BLOCK);
- final Entitlement entitlement = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, entitlementDate, billingDate, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, entitlementDate, billingDate, false, true, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
+ final Entitlement entitlement = entitlementApi.getEntitlementForId(entitlementId, callContext);
assertEquals(entitlement.getState(), EntitlementState.ACTIVE);
assertEquals(entitlement.getEffectiveStartDate(), initialDate);
@@ -732,8 +751,9 @@ public class TestDefaultEntitlementApi extends EntitlementTestSuiteWithEmbeddedD
final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Shotgun", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null);
testListener.pushExpectedEvents(NextEvent.BLOCK, NextEvent.CREATE);
- final Entitlement entitlement = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, entitlementDate, billingDate, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, entitlementDate, billingDate, false, true, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
+ final Entitlement entitlement = entitlementApi.getEntitlementForId(entitlementId, callContext);
assertEquals(entitlement.getState(), EntitlementState.ACTIVE);
assertEquals(entitlement.getEffectiveStartDate(), entitlementDate);
@@ -752,8 +772,9 @@ public class TestDefaultEntitlementApi extends EntitlementTestSuiteWithEmbeddedD
final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Shotgun", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null);
testListener.pushExpectedEvents(NextEvent.BLOCK, NextEvent.CREATE);
- final Entitlement entitlement = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, entitlementDate, billingDate, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, entitlementDate, billingDate, false, true, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
+ final Entitlement entitlement = entitlementApi.getEntitlementForId(entitlementId, callContext);
assertEquals(entitlement.getState(), EntitlementState.ACTIVE);
assertEquals(entitlement.getEffectiveStartDate(), entitlementDate);
@@ -772,8 +793,9 @@ public class TestDefaultEntitlementApi extends EntitlementTestSuiteWithEmbeddedD
final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Shotgun", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null);
testListener.pushExpectedEvents(NextEvent.BLOCK, NextEvent.CREATE);
- final Entitlement entitlement = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, entitlementDate, billingDate, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, entitlementDate, billingDate, false, true, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
+ final Entitlement entitlement = entitlementApi.getEntitlementForId(entitlementId, callContext);
assertEquals(entitlement.getState(), EntitlementState.ACTIVE);
assertEquals(entitlement.getEffectiveStartDate(), initialDate);
@@ -811,11 +833,11 @@ public class TestDefaultEntitlementApi extends EntitlementTestSuiteWithEmbeddedD
// We expect 3 {BLOCK, CREATE} events for the 3 subscriptions created,.
testListener.pushExpectedEvents(NextEvent.BLOCK, NextEvent.CREATE, NextEvent.BLOCK, NextEvent.CREATE, NextEvent.BLOCK, NextEvent.CREATE);
- final List<Entitlement> entitlements = entitlementApi.createBaseEntitlementsWithAddOns(account.getId(), baseEntitlementWithAddOnsSpecifiers, true, ImmutableList.<PluginProperty>of(), callContext);
+ final List<UUID> entitlementIds = entitlementApi.createBaseEntitlementsWithAddOns(account.getId(), baseEntitlementWithAddOnsSpecifiers, true, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
// Retun only the created subscriptions
- Assert.assertEquals(entitlements.size(), 3);
+ Assert.assertEquals(entitlementIds.size(), 3);
final List<Entitlement> entitlementsForBundle1 = entitlementApi.getAllEntitlementsForAccountIdAndExternalKey(account.getId(), bundleKey1, callContext);
Assert.assertEquals(entitlementsForBundle1.size(), 2);
@@ -877,8 +899,9 @@ public class TestDefaultEntitlementApi extends EntitlementTestSuiteWithEmbeddedD
// Create STANDALONE entitlement
testListener.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK);
- final Entitlement baseEntitlement = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, null, null, false, false, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID baseEntitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, null, null, false, false, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
+ final Entitlement baseEntitlement = entitlementApi.getEntitlementForId(baseEntitlementId, callContext);
assertEquals(baseEntitlement.getAccountId(), account.getId());
assertEquals(baseEntitlement.getExternalKey(), account.getExternalKey());
@@ -889,8 +912,9 @@ public class TestDefaultEntitlementApi extends EntitlementTestSuiteWithEmbeddedD
// Add another STANDALONE entitlement
final PlanPhaseSpecifier spec1 = new PlanPhaseSpecifier("Knife", BillingPeriod.MONTHLY, "notrial", null);
testListener.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK);
- final Entitlement anotherStandaloneEntitlement = entitlementApi.addEntitlement(baseEntitlement.getBundleId(), spec1, null, initialDate, initialDate, false, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID anotherStandaloneEntitlementId = entitlementApi.addEntitlement(baseEntitlement.getBundleId(), spec1, null, initialDate, initialDate, false, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
+ final Entitlement anotherStandaloneEntitlement = entitlementApi.getEntitlementForId(anotherStandaloneEntitlementId, callContext);
assertEquals(anotherStandaloneEntitlement.getAccountId(), account.getId());
assertEquals(anotherStandaloneEntitlement.getExternalKey(), account.getExternalKey());
diff --git a/entitlement/src/test/java/org/killbill/billing/entitlement/api/TestDefaultSubscriptionApi.java b/entitlement/src/test/java/org/killbill/billing/entitlement/api/TestDefaultSubscriptionApi.java
index 6fca4f6..cb1aea3 100644
--- a/entitlement/src/test/java/org/killbill/billing/entitlement/api/TestDefaultSubscriptionApi.java
+++ b/entitlement/src/test/java/org/killbill/billing/entitlement/api/TestDefaultSubscriptionApi.java
@@ -1,7 +1,9 @@
/*
* Copyright 2010-2013 Ning, Inc.
+ * Copyright 2014-2018 Groupon, Inc
+ * Copyright 2014-2018 The Billing Project, LLC
*
- * Ning licenses this file to you under the Apache License, version 2.0
+ * 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
* License. You may obtain a copy of the License at:
*
@@ -30,7 +32,6 @@ import org.killbill.billing.api.TestApiListener.NextEvent;
import org.killbill.billing.catalog.api.BillingActionPolicy;
import org.killbill.billing.catalog.api.BillingPeriod;
import org.killbill.billing.catalog.api.PlanPhaseSpecifier;
-import org.killbill.billing.catalog.api.PlanSpecifier;
import org.killbill.billing.catalog.api.PriceListSet;
import org.killbill.billing.entitlement.EntitlementService;
import org.killbill.billing.entitlement.EntitlementTestSuiteWithEmbeddedDB;
@@ -61,15 +62,17 @@ public class TestDefaultSubscriptionApi extends EntitlementTestSuiteWithEmbedded
final Account account = createAccount(getAccountData(7));
final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Shotgun", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null);
testListener.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK);
- final Entitlement entitlement1 = entitlementApi.createBaseEntitlement(account.getId(), spec, UUID.randomUUID().toString(), null, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID entitlement1Id = entitlementApi.createBaseEntitlement(account.getId(), spec, UUID.randomUUID().toString(), null, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final Entitlement entitlement1 = entitlementApi.getEntitlementForId(entitlement1Id, callContext);
// Sleep 1 sec so created date are apart from each other and ordering in the bundle does not default on the UUID which is random.
try {
Thread.sleep(1000);
} catch (InterruptedException ignore) {
}
testListener.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK);
- final Entitlement entitlement2 = entitlementApi.createBaseEntitlement(account.getId(), spec, UUID.randomUUID().toString(), null, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID entitlement2Id = entitlementApi.createBaseEntitlement(account.getId(), spec, UUID.randomUUID().toString(), null, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
+ final Entitlement entitlement2 = entitlementApi.getEntitlementForId(entitlement2Id, callContext);
testListener.pushExpectedEvents(NextEvent.BLOCK);
entitlementUtils.setBlockingStateAndPostBlockingTransitionEvent(new DefaultBlockingState(account.getId(), BlockingStateType.ACCOUNT, "stateName", "service", false, false, false, clock.getUTCNow()),
@@ -114,8 +117,9 @@ public class TestDefaultSubscriptionApi extends EntitlementTestSuiteWithEmbedded
// Create entitlement and check each field
testListener.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK);
- final Entitlement entitlement = entitlementApi.createBaseEntitlement(account.getId(), spec, externalKey, null, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, externalKey, null, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
+ final Entitlement entitlement = entitlementApi.getEntitlementForId(entitlementId, callContext);
assertEquals(entitlement.getAccountId(), account.getId());
assertEquals(entitlement.getExternalKey(), externalKey);
@@ -148,8 +152,9 @@ public class TestDefaultSubscriptionApi extends EntitlementTestSuiteWithEmbedded
// Create entitlement and check each field
testListener.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK);
- final Entitlement entitlement2 = entitlementApi.createBaseEntitlement(account.getId(), spec2, externalKey, null, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID entitlement2Id = entitlementApi.createBaseEntitlement(account.getId(), spec2, externalKey, null, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
+ final Entitlement entitlement2 = entitlementApi.getEntitlementForId(entitlement2Id, callContext);
assertEquals(entitlement2.getAccountId(), account.getId());
assertEquals(entitlement2.getExternalKey(), externalKey);
@@ -219,8 +224,9 @@ public class TestDefaultSubscriptionApi extends EntitlementTestSuiteWithEmbedded
// Create entitlement
testListener.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK);
final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Shotgun", BillingPeriod.ANNUAL, PriceListSet.DEFAULT_PRICELIST_NAME, null);
- final Entitlement baseEntitlement = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID baseEntitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
+ final Entitlement baseEntitlement = entitlementApi.getEntitlementForId(baseEntitlementId, callContext);
// Get the phase event out of the way
testListener.pushExpectedEvents(NextEvent.PHASE);
@@ -277,7 +283,8 @@ public class TestDefaultSubscriptionApi extends EntitlementTestSuiteWithEmbedded
final LocalDate effectiveDate = initialDate.plusMonths(1);
// Create entitlement and check each field
- final Entitlement entitlement = entitlementApi.createBaseEntitlement(account.getId(), spec, externalKey, null, effectiveDate, effectiveDate, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, externalKey, null, effectiveDate, effectiveDate, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final Entitlement entitlement = entitlementApi.getEntitlementForId(entitlementId, callContext);
final Subscription subscription = subscriptionApi.getSubscriptionForEntitlementId(entitlement.getId(), callContext);
@@ -309,7 +316,8 @@ public class TestDefaultSubscriptionApi extends EntitlementTestSuiteWithEmbedded
final LocalDate futureDate = new LocalDate(2013, 9, 1);
// No CREATE event as this is set in the future
- final Entitlement createdEntitlement = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, futureDate, futureDate, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID createdEntitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, futureDate, futureDate, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final Entitlement createdEntitlement = entitlementApi.getEntitlementForId(createdEntitlementId, callContext);
assertEquals(createdEntitlement.getEffectiveStartDate().compareTo(futureDate), 0);
assertEquals(createdEntitlement.getEffectiveEndDate(), null);
@@ -337,7 +345,8 @@ public class TestDefaultSubscriptionApi extends EntitlementTestSuiteWithEmbedded
final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Shotgun", BillingPeriod.ANNUAL, PriceListSet.DEFAULT_PRICELIST_NAME, null);
testListener.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK);
- final Entitlement createdEntitlement = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, initialDate, initialDate, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID createdEntitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, initialDate, initialDate, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final Entitlement createdEntitlement = entitlementApi.getEntitlementForId(createdEntitlementId, callContext);
final Iterable<BlockingState> iterableForCreateState = subscriptionApi.getBlockingStates(account.getId(), ImmutableList.of(BlockingStateType.SUBSCRIPTION), null, OrderingType.ASCENDING, SubscriptionApi.ALL_EVENTS, callContext);
assertTrue(iterableForCreateState.iterator().hasNext());
@@ -412,8 +421,9 @@ public class TestDefaultSubscriptionApi extends EntitlementTestSuiteWithEmbedded
// Create entitlement and check each field
testListener.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK);
- final Entitlement baseEntitlement = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID baseEntitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
+ final Entitlement baseEntitlement = entitlementApi.getEntitlementForId(baseEntitlementId, callContext);
clock.addDays(5);
@@ -486,10 +496,12 @@ public class TestDefaultSubscriptionApi extends EntitlementTestSuiteWithEmbedded
// Create entitlement and check each field
testListener.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK);
- final Entitlement entitlement = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
+ final Entitlement entitlement = entitlementApi.getEntitlementForId(entitlementId, callContext);
clock.addDays(1);
+ clock.addDeltaFromReality(5000);
assertListenerStatus();
testListener.pushExpectedEvent(NextEvent.BLOCK);
@@ -506,14 +518,12 @@ public class TestDefaultSubscriptionApi extends EntitlementTestSuiteWithEmbedded
assertEquals(latestEntitlement.getLastActivePlan().getProduct().getName(), "Shotgun");
}
- try {
- entitlement.changePlanWithDate(new PlanPhaseSpecifier("Assault-Rifle", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME), null, clock.getUTCToday(), ImmutableList.<PluginProperty>of(), callContext);
- fail();
- } catch (final EntitlementApiException e) {
- assertEquals(e.getCode(), ErrorCode.BLOCK_BLOCKED_ACTION.getCode());
- final Entitlement latestEntitlement = entitlementApi.getEntitlementForId(entitlement.getId(), callContext);
- assertEquals(latestEntitlement.getLastActivePlan().getProduct().getName(), "Shotgun");
- }
+ // If a LocalDate is passed, it will align with the reference time (2013-08-08T00:00:00.000Z), which will fall before the blocking state above (+5s added above)
+ testListener.pushExpectedEvent(NextEvent.CHANGE);
+ entitlement.changePlanWithDate(new PlanPhaseSpecifier("Assault-Rifle", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME), null, clock.getUTCToday(), ImmutableList.<PluginProperty>of(), callContext);
+ assertListenerStatus();
+ final Entitlement latestEntitlement = entitlementApi.getEntitlementForId(entitlement.getId(), callContext);
+ assertEquals(latestEntitlement.getLastActivePlan().getProduct().getName(), "Assault-Rifle");
}
@Test(groups = "slow")
@@ -526,8 +536,9 @@ public class TestDefaultSubscriptionApi extends EntitlementTestSuiteWithEmbedded
// Create entitlement
testListener.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK);
final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Shotgun", BillingPeriod.ANNUAL, PriceListSet.DEFAULT_PRICELIST_NAME, null);
- final Entitlement baseEntitlement = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID baseEntitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
+ final Entitlement baseEntitlement = entitlementApi.getEntitlementForId(baseEntitlementId, callContext);
// 2013-08-10 : Stay in TRIAL to ensure IMMEDIATE billing policy is used
clock.addDays(3);
diff --git a/entitlement/src/test/java/org/killbill/billing/entitlement/api/TestRegessionSubscriptionApi.java b/entitlement/src/test/java/org/killbill/billing/entitlement/api/TestRegessionSubscriptionApi.java
index 6576c09..0721b06 100644
--- a/entitlement/src/test/java/org/killbill/billing/entitlement/api/TestRegessionSubscriptionApi.java
+++ b/entitlement/src/test/java/org/killbill/billing/entitlement/api/TestRegessionSubscriptionApi.java
@@ -1,6 +1,6 @@
/*
- * 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
@@ -17,39 +17,23 @@
package org.killbill.billing.entitlement.api;
-import java.util.Iterator;
import java.util.List;
import java.util.UUID;
-import org.joda.time.DateTime;
import org.joda.time.LocalDate;
-import org.killbill.billing.ErrorCode;
-import org.killbill.billing.OrderingType;
import org.killbill.billing.account.api.Account;
-import org.killbill.billing.account.api.AccountApiException;
import org.killbill.billing.api.TestApiListener.NextEvent;
-import org.killbill.billing.catalog.api.BillingActionPolicy;
import org.killbill.billing.catalog.api.BillingPeriod;
import org.killbill.billing.catalog.api.PlanPhaseSpecifier;
import org.killbill.billing.catalog.api.PriceListSet;
-import org.killbill.billing.catalog.api.ProductCategory;
-import org.killbill.billing.entitlement.EntitlementService;
import org.killbill.billing.entitlement.EntitlementTestSuiteWithEmbeddedDB;
-import org.killbill.billing.entitlement.api.Entitlement.EntitlementActionPolicy;
-import org.killbill.billing.entitlement.api.Entitlement.EntitlementState;
-import org.killbill.billing.junction.DefaultBlockingState;
import org.killbill.billing.payment.api.PluginProperty;
-import org.killbill.billing.util.api.AuditLevel;
-import org.killbill.billing.util.audit.AuditLog;
-import org.killbill.billing.util.audit.ChangeType;
import org.testng.Assert;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableList;
import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertNull;
-import static org.testng.Assert.assertTrue;
public class TestRegessionSubscriptionApi extends EntitlementTestSuiteWithEmbeddedDB {
@@ -65,7 +49,8 @@ public class TestRegessionSubscriptionApi extends EntitlementTestSuiteWithEmbedd
final Account account = createAccount(getAccountData(7));
final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Shotgun", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null);
testListener.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK);
- final Entitlement entitlement = entitlementApi.createBaseEntitlement(account.getId(), spec, UUID.randomUUID().toString(), null, entitlementEffectiveDate, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, UUID.randomUUID().toString(), null, entitlementEffectiveDate, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final Entitlement entitlement = entitlementApi.getEntitlementForId(entitlementId, callContext);
// Because of the BlockingState event ENT_STARTED, the entitlement date should be correctly set
Assert.assertEquals(entitlement.getEffectiveStartDate(), entitlementEffectiveDate);
diff --git a/entitlement/src/test/java/org/killbill/billing/entitlement/block/TestBlockingApi.java b/entitlement/src/test/java/org/killbill/billing/entitlement/block/TestBlockingApi.java
index 925a058..55a6964 100644
--- a/entitlement/src/test/java/org/killbill/billing/entitlement/block/TestBlockingApi.java
+++ b/entitlement/src/test/java/org/killbill/billing/entitlement/block/TestBlockingApi.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
@@ -142,8 +142,9 @@ public class TestBlockingApi extends EntitlementTestSuiteWithEmbeddedDB {
final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Shotgun", BillingPeriod.ANNUAL, PriceListSet.DEFAULT_PRICELIST_NAME, null);
testListener.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK);
- Entitlement baseEntitlement = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID baseEntitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
+ Entitlement baseEntitlement = entitlementApi.getEntitlementForId(baseEntitlementId, callContext);
assertEquals(baseEntitlement.getState(), EntitlementState.BLOCKED);
@@ -234,8 +235,9 @@ public class TestBlockingApi extends EntitlementTestSuiteWithEmbeddedDB {
final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("shotgun-monthly", null);
testListener.pushExpectedEvents(NextEvent.BLOCK, NextEvent.CREATE);
- final Entitlement entitlement = entitlementApi.createBaseEntitlement(account.getId(), spec, "xyzqe", null, initialDate.minusDays(3), null, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID baseEntitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, "xyzqe", null, initialDate.minusDays(3), null, false, true, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
+ final Entitlement entitlement = entitlementApi.getEntitlementForId(baseEntitlementId, callContext);
testListener.pushExpectedEvent(NextEvent.BLOCK);
final BlockingState blockChangeAccount = new DefaultBlockingState(account.getId(), BlockingStateType.ACCOUNT, "State1", "Service1", true, false, false, clock.getUTCNow());
@@ -276,8 +278,9 @@ public class TestBlockingApi extends EntitlementTestSuiteWithEmbeddedDB {
final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("shotgun-monthly", null);
testListener.pushExpectedEvents(NextEvent.BLOCK, NextEvent.CREATE);
- final Entitlement entitlement = entitlementApi.createBaseEntitlement(account.getId(), spec, "xyzqe", null, initialDate.minusDays(3), null, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID baseEntitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, "xyzqe", null, initialDate.minusDays(3), null, false, true, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
+ final Entitlement entitlement = entitlementApi.getEntitlementForId(baseEntitlementId, callContext);
// Create future BlockingState
final LocalDate blockingChange = initialDate.plusDays(3);
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 bb480fa..e8ac66b 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
@@ -64,6 +64,8 @@ public class TestBlockingChecker extends EntitlementTestSuiteNoDB {
try {
Mockito.when(subscriptionInternalApi.getBundleFromId(Mockito.<UUID>any(), Mockito.<InternalTenantContext>any())).thenReturn(bundle);
+ Mockito.when(subscriptionInternalApi.getAccountIdFromBundleId(Mockito.<UUID>any(), Mockito.<InternalTenantContext>any())).thenReturn(accountId);
+ Mockito.when(subscriptionInternalApi.getBundleIdFromSubscriptionId(Mockito.<UUID>any(), Mockito.<InternalTenantContext>any())).thenReturn(bundleId);
} catch (SubscriptionBaseApiException e) {
Assert.fail(e.toString());
}
diff --git a/entitlement/src/test/java/org/killbill/billing/entitlement/dao/TestBlockingDao.java b/entitlement/src/test/java/org/killbill/billing/entitlement/dao/TestBlockingDao.java
index 0e1b822..610f4b1 100644
--- a/entitlement/src/test/java/org/killbill/billing/entitlement/dao/TestBlockingDao.java
+++ b/entitlement/src/test/java/org/killbill/billing/entitlement/dao/TestBlockingDao.java
@@ -22,6 +22,7 @@ import java.util.List;
import java.util.UUID;
import org.joda.time.LocalDate;
+import org.killbill.billing.account.api.AccountApiException;
import org.killbill.billing.api.TestApiListener.NextEvent;
import org.killbill.billing.entitlement.EntitlementTestSuiteWithEmbeddedDB;
import org.killbill.billing.entitlement.api.BlockingState;
@@ -36,8 +37,8 @@ import com.google.common.collect.ImmutableMap;
public class TestBlockingDao extends EntitlementTestSuiteWithEmbeddedDB {
@Test(groups = "slow", description = "Check BlockingStateDao with a single service")
- public void testDaoWithOneService() {
- final UUID uuid = UUID.randomUUID();
+ public void testDaoWithOneService() throws AccountApiException {
+ final UUID uuid = createAccount(getAccountData(1)).getId();
final String overdueStateName = "WayPassedItMan";
final String service = "TEST";
@@ -71,7 +72,7 @@ public class TestBlockingDao extends EntitlementTestSuiteWithEmbeddedDB {
@Test(groups = "slow", description = "Check BlockingStateDao with multiple services")
public void testDaoWithMultipleServices() throws Exception {
- final UUID uuid = UUID.randomUUID();
+ final UUID uuid = createAccount(getAccountData(1)).getId();
final String overdueStateName = "WayPassedItMan";
final String service1 = "TEST";
diff --git a/entitlement/src/test/java/org/killbill/billing/entitlement/dao/TestDefaultBlockingStateDao.java b/entitlement/src/test/java/org/killbill/billing/entitlement/dao/TestDefaultBlockingStateDao.java
index 4165b43..1fae808 100644
--- a/entitlement/src/test/java/org/killbill/billing/entitlement/dao/TestDefaultBlockingStateDao.java
+++ b/entitlement/src/test/java/org/killbill/billing/entitlement/dao/TestDefaultBlockingStateDao.java
@@ -58,8 +58,9 @@ public class TestDefaultBlockingStateDao extends EntitlementTestSuiteWithEmbedde
// See TestEntitlementUtils for a more comprehensive test
final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Shotgun", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null);
testListener.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK);
- final Entitlement entitlement = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
+ final Entitlement entitlement = entitlementApi.getEntitlementForId(entitlementId, callContext);
final BlockingStateType type = BlockingStateType.SUBSCRIPTION;
final String state = "state";
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 bc88fab..c2b31fd 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
@@ -72,14 +72,16 @@ public class TestEntitlementUtils extends EntitlementTestSuiteWithEmbeddedDB {
// Create base entitlement
testListener.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK);
final PlanPhaseSpecifier baseSpec = new PlanPhaseSpecifier("Shotgun", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null);
- baseEntitlement = (DefaultEntitlement) entitlementApi.createBaseEntitlement(account.getId(), baseSpec, account.getExternalKey(), null, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID baseEntitlementId = entitlementApi.createBaseEntitlement(account.getId(), baseSpec, account.getExternalKey(), null, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
+ baseEntitlement = (DefaultEntitlement) entitlementApi.getEntitlementForId(baseEntitlementId, callContext);
// Add ADD_ON
testListener.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK);
final PlanPhaseSpecifier addOnSpec = new PlanPhaseSpecifier("Telescopic-Scope", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null);
- addOnEntitlement = (DefaultEntitlement) entitlementApi.addEntitlement(baseEntitlement.getBundleId(), addOnSpec, null, null, null, false, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID addOnEntitlementId = entitlementApi.addEntitlement(baseEntitlement.getBundleId(), addOnSpec, null, null, null, false, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
+ addOnEntitlement = (DefaultEntitlement) entitlementApi.getEntitlementForId(addOnEntitlementId, callContext);
// Verify the initial state
checkFutureBlockingStatesToCancel(baseEntitlement, null, null);
@@ -266,7 +268,7 @@ public class TestEntitlementUtils extends EntitlementTestSuiteWithEmbeddedDB {
// Add a second ADD_ON (Laser-Scope is available, not included)
testListener.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK);
final PlanPhaseSpecifier secondAddOnSpec = new PlanPhaseSpecifier("Laser-Scope", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null);
- final DefaultEntitlement secondAddOnEntitlement = (DefaultEntitlement) entitlementApi.addEntitlement(baseEntitlement.getBundleId(), secondAddOnSpec, null, clock.getUTCToday(), clock.getUTCToday(), false, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID secondAddOnEntitlementId = entitlementApi.addEntitlement(baseEntitlement.getBundleId(), secondAddOnSpec, null, clock.getUTCToday(), clock.getUTCToday(), false, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
// Change plan EOT to Assault-Rifle (Telescopic-Scope is included)
@@ -277,7 +279,7 @@ public class TestEntitlementUtils extends EntitlementTestSuiteWithEmbeddedDB {
// Verify the blocking states DAO adds events not on disk for the first add-on...
checkBlockingStatesDAO(changedBaseEntitlement, addOnEntitlement, baseEffectiveCancellationOrChangeDate, false);
// ...but not for the second one
- final List<BlockingState> blockingStatesForSecondAddOn = blockingStatesForBlockedId(secondAddOnEntitlement.getId());
+ final List<BlockingState> blockingStatesForSecondAddOn = blockingStatesForBlockedId(secondAddOnEntitlementId);
Assert.assertEquals(blockingStatesForSecondAddOn.size(), 1);
}
@@ -325,8 +327,9 @@ public class TestEntitlementUtils extends EntitlementTestSuiteWithEmbeddedDB {
// Add a second ADD_ON
testListener.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK, NextEvent.PHASE);
final PlanPhaseSpecifier addOn2Spec = new PlanPhaseSpecifier("Telescopic-Scope", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null);
- final Entitlement addOn2Entitlement = entitlementApi.addEntitlement(baseEntitlement.getBundleId(), addOn2Spec, null, initialDate, initialDate, false, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID addOn2EntitlementId = entitlementApi.addEntitlement(baseEntitlement.getBundleId(), addOn2Spec, null, initialDate, initialDate, false, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
+ final Entitlement addOn2Entitlement = entitlementApi.getEntitlementForId(addOn2EntitlementId, callContext);
// Date prior to the base cancellation date to verify it is not impacted by the base cancellation (in contrary to the second add-on)
final LocalDate addOn1CancellationDate = new LocalDate(2013, 9, 9);
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/notification/DefaultNextBillingDateNotifier.java b/invoice/src/main/java/org/killbill/billing/invoice/notification/DefaultNextBillingDateNotifier.java
index 98ee28a..79949d9 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/notification/DefaultNextBillingDateNotifier.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/notification/DefaultNextBillingDateNotifier.java
@@ -23,9 +23,7 @@ import java.util.UUID;
import org.joda.time.DateTime;
import org.killbill.billing.invoice.InvoiceListener;
import org.killbill.billing.invoice.api.DefaultInvoiceService;
-import org.killbill.billing.subscription.api.SubscriptionBase;
import org.killbill.billing.subscription.api.SubscriptionBaseInternalApi;
-import org.killbill.billing.subscription.api.user.SubscriptionBaseApiException;
import org.killbill.billing.util.callcontext.InternalCallContextFactory;
import org.killbill.clock.Clock;
import org.killbill.notificationq.api.NotificationEvent;
@@ -84,21 +82,12 @@ public class DefaultNextBillingDateNotifier extends RetryableService implements
// Just to ensure compatibility with json that might not have that targetDate field (old versions < 0.13.6)
final DateTime targetDate = key.getTargetDate() != null ? key.getTargetDate() : eventDate;
final UUID firstSubscriptionId = key.getUuidKeys().iterator().next();
- try {
- final SubscriptionBase subscription = subscriptionApi.getSubscriptionFromId(firstSubscriptionId, internalCallContextFactory.createInternalTenantContext(tenantRecordId, accountRecordId));
- if (subscription == null) {
- log.warn("Unable to retrieve subscriptionId='{}' for event {}", firstSubscriptionId, key);
- return;
- }
- if (key.isDryRunForInvoiceNotification() != null && // Just to ensure compatibility with json that might not have that field (old versions < 0.13.6)
- key.isDryRunForInvoiceNotification()) {
- processEventForInvoiceNotification(firstSubscriptionId, targetDate, userToken, accountRecordId, tenantRecordId);
- } else {
- final boolean isRescheduled = key.isRescheduled() == Boolean.TRUE; // Handle null value (old versions < 0.19.7)
- processEventForInvoiceGeneration(firstSubscriptionId, targetDate, isRescheduled, userToken, accountRecordId, tenantRecordId);
- }
- } catch (final SubscriptionBaseApiException e) {
- log.warn("Error retrieving subscriptionId='{}'", firstSubscriptionId, e);
+ if (key.isDryRunForInvoiceNotification() != null && // Just to ensure compatibility with json that might not have that field (old versions < 0.13.6)
+ key.isDryRunForInvoiceNotification()) {
+ processEventForInvoiceNotification(firstSubscriptionId, targetDate, userToken, accountRecordId, tenantRecordId);
+ } else {
+ final boolean isRescheduled = key.isRescheduled() == Boolean.TRUE; // Handle null value (old versions < 0.19.7)
+ processEventForInvoiceGeneration(firstSubscriptionId, targetDate, isRescheduled, userToken, accountRecordId, tenantRecordId);
}
}
};
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/SubscriptionResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/SubscriptionResource.java
index c264f4d..9bacaf2 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/SubscriptionResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/SubscriptionResource.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
@@ -20,7 +20,9 @@ package org.killbill.billing.jaxrs.resources;
import java.math.BigDecimal;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.HashMap;
+import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.UUID;
@@ -201,13 +203,12 @@ public class SubscriptionResource extends JaxRsResourceBase {
final boolean isReusingExistingBundle = ProductCategory.ADD_ON.name().equals(entitlement.getProductCategory()) ||
(ProductCategory.STANDALONE.name().equals(entitlement.getProductCategory()) && entitlement.getBundleId() != null);
-
final Iterable<PluginProperty> pluginProperties = extractPluginProperties(pluginPropertiesString);
final CallContext callContext = context.createCallContextNoAccountId(createdBy, reason, comment, request);
- final EntitlementCallCompletionCallback<Entitlement> callback = new EntitlementCallCompletionCallback<Entitlement>() {
+ final EntitlementCallCompletionCallback<UUID> callback = new EntitlementCallCompletionCallback<UUID>() {
@Override
- public Entitlement doOperation(final CallContext ctx) throws InterruptedException, TimeoutException, EntitlementApiException, SubscriptionApiException, AccountApiException {
+ public UUID doOperation(final CallContext ctx) throws InterruptedException, TimeoutException, EntitlementApiException, SubscriptionApiException, AccountApiException {
final Account account = getAccountFromSubscriptionJson(entitlement, callContext);
final PhaseType phaseType = entitlement.getPhaseType() != null ? PhaseType.valueOf(entitlement.getPhaseType()) : null;
@@ -219,12 +220,13 @@ public class SubscriptionResource extends JaxRsResourceBase {
final LocalDate resolvedEntitlementDate = requestedDate != null ? toLocalDate(requestedDate) : toLocalDate(entitlementDate);
final LocalDate resolvedBillingDate = requestedDate != null ? toLocalDate(requestedDate) : toLocalDate(billingDate);
final List<PlanPhasePriceOverride> overrides = PhasePriceOverrideJson.toPlanPhasePriceOverrides(entitlement.getPriceOverrides(), spec, account.getCurrency());
- final Entitlement result = isReusingExistingBundle
- ? entitlementApi.addEntitlement(getBundleIdForAddOnCreation(entitlement), spec, overrides, resolvedEntitlementDate, resolvedBillingDate, isMigrated, pluginProperties, callContext)
- : entitlementApi.createBaseEntitlement(account.getId(), spec, entitlement.getExternalKey(), overrides, resolvedEntitlementDate, resolvedBillingDate, isMigrated, renameKeyIfExistsAndUnused, pluginProperties, callContext);
+ final UUID result = isReusingExistingBundle
+ ? entitlementApi.addEntitlement(getBundleIdForAddOnCreation(entitlement), spec, overrides, resolvedEntitlementDate, resolvedBillingDate, isMigrated, pluginProperties, callContext)
+ : entitlementApi.createBaseEntitlement(account.getId(), spec, entitlement.getExternalKey(), overrides, resolvedEntitlementDate, resolvedBillingDate, isMigrated, renameKeyIfExistsAndUnused, pluginProperties, callContext);
if (newBCD != null) {
- result.updateBCD(newBCD, null, callContext);
+ final Entitlement createdEntitlement = entitlementApi.getEntitlementForId(result, callContext);
+ createdEntitlement.updateBCD(newBCD, null, callContext);
}
return result;
}
@@ -245,12 +247,12 @@ public class SubscriptionResource extends JaxRsResourceBase {
}
@Override
- public Response doResponseOk(final Entitlement createdEntitlement) {
- return uriBuilder.buildResponse(uriInfo, SubscriptionResource.class, "getEntitlement", createdEntitlement.getId(), request);
+ public Response doResponseOk(final UUID createdEntitlementId) {
+ return uriBuilder.buildResponse(uriInfo, SubscriptionResource.class, "getEntitlement", createdEntitlementId, request);
}
};
- final EntitlementCallCompletion<Entitlement> callCompletionCreation = new EntitlementCallCompletion<Entitlement>();
+ final EntitlementCallCompletion<UUID> callCompletionCreation = new EntitlementCallCompletion<UUID>();
return callCompletionCreation.withSynchronization(callback, timeoutSec, callCompletion, callContext);
}
@@ -303,22 +305,21 @@ public class SubscriptionResource extends JaxRsResourceBase {
return createEntitlementsWithAddOnsInternal(entitlementsWithAddOns, requestedDate, entitlementDate, billingDate, isMigrated, renameKeyIfExistsAndUnused, callCompletion, timeoutSec, pluginPropertiesString, createdBy, reason, comment, request, uriInfo, ObjectType.ACCOUNT);
}
-
- public Response createEntitlementsWithAddOnsInternal(final List<BulkSubscriptionsBundleJson> entitlementsWithAddOns,
- final String requestedDate,
- final String entitlementDate,
- final String billingDate,
- final Boolean isMigrated,
- final Boolean renameKeyIfExistsAndUnused,
- final Boolean callCompletion,
- final long timeoutSec,
- final List<String> pluginPropertiesString,
- final String createdBy,
- final String reason,
- final String comment,
- final HttpServletRequest request,
- final UriInfo uriInfo, final ObjectType responseObject) throws EntitlementApiException, AccountApiException, SubscriptionApiException {
-
+ private Response createEntitlementsWithAddOnsInternal(final List<BulkSubscriptionsBundleJson> entitlementsWithAddOns,
+ final String requestedDate,
+ final String entitlementDate,
+ final String billingDate,
+ final Boolean isMigrated,
+ final Boolean renameKeyIfExistsAndUnused,
+ final Boolean callCompletion,
+ final long timeoutSec,
+ final List<String> pluginPropertiesString,
+ final String createdBy,
+ final String reason,
+ final String comment,
+ final HttpServletRequest request,
+ final UriInfo uriInfo,
+ final ObjectType responseObject) throws EntitlementApiException, AccountApiException, SubscriptionApiException {
Preconditions.checkArgument(Iterables.size(entitlementsWithAddOns) > 0, "Subscription bulk list mustn't be null or empty.");
logDeprecationParameterWarningIfNeeded(QUERY_REQUESTED_DT, QUERY_ENTITLEMENT_REQUESTED_DT, QUERY_BILLING_REQUESTED_DT);
@@ -341,7 +342,6 @@ public class SubscriptionResource extends JaxRsResourceBase {
verifyNumberOfElements(Iterables.size(baseEntitlements), 1, "Only one BASE product is allowed per bundle.");
final SubscriptionJson baseEntitlement = baseEntitlements.iterator().next();
-
final Iterable<SubscriptionJson> addonEntitlements = Iterables.filter(
bulkBaseEntitlementWithAddOns.getBaseEntitlementAndAddOns(), new Predicate<SubscriptionJson>() {
@Override
@@ -351,43 +351,53 @@ public class SubscriptionResource extends JaxRsResourceBase {
}
);
-
final List<EntitlementSpecifier> entitlementSpecifierList = buildEntitlementSpecifierList(baseEntitlement, addonEntitlements, account.getCurrency());
// create the baseEntitlementSpecifierWithAddOns
final LocalDate resolvedEntitlementDate = requestedDate != null ? toLocalDate(requestedDate) : toLocalDate(entitlementDate);
final LocalDate resolvedBillingDate = requestedDate != null ? toLocalDate(requestedDate) : toLocalDate(billingDate);
- BaseEntitlementWithAddOnsSpecifier baseEntitlementSpecifierWithAddOns = buildBaseEntitlementWithAddOnsSpecifier(entitlementSpecifierList, resolvedEntitlementDate, resolvedBillingDate, null, baseEntitlement, isMigrated);
+ final BaseEntitlementWithAddOnsSpecifier baseEntitlementSpecifierWithAddOns = buildBaseEntitlementWithAddOnsSpecifier(entitlementSpecifierList, resolvedEntitlementDate, resolvedBillingDate, null, baseEntitlement, isMigrated);
baseEntitlementWithAddOnsSpecifierList.add(baseEntitlementSpecifierWithAddOns);
}
- final EntitlementCallCompletionCallback<List<Entitlement>> callback = new EntitlementCallCompletionCallback<List<Entitlement>>() {
+ final EntitlementCallCompletionCallback<List<UUID>> callback = new EntitlementCallCompletionCallback<List<UUID>>() {
@Override
- public List<Entitlement> doOperation(final CallContext ctx) throws InterruptedException, TimeoutException, EntitlementApiException, SubscriptionApiException, AccountApiException {
+ public List<UUID> doOperation(final CallContext ctx) throws InterruptedException, TimeoutException, EntitlementApiException, SubscriptionApiException, AccountApiException {
return entitlementApi.createBaseEntitlementsWithAddOns(account.getId(), baseEntitlementWithAddOnsSpecifierList, renameKeyIfExistsAndUnused, pluginProperties, callContext);
}
+
@Override
public boolean isImmOperation() {
return true;
}
+
@Override
- public Response doResponseOk(final List<Entitlement> entitlements) {
+ public Response doResponseOk(final List<UUID> entitlementIds) {
+ final Collection<String> bundleIds = new LinkedHashSet<String>();
+ try {
+ for (final Entitlement entitlement : entitlementApi.getAllEntitlementsForAccountId(account.getId(), callContext)) {
+ if (entitlementIds.contains(entitlement.getId())) {
+ bundleIds.add(entitlement.getBundleId().toString());
+ }
+ }
+ } catch (final EntitlementApiException e) {
+ return Response.status(Status.INTERNAL_SERVER_ERROR).build();
+ }
+
if (responseObject == ObjectType.ACCOUNT) {
- return uriBuilder.buildResponse(uriInfo, AccountResource.class, "getAccountBundles", entitlements.get(0).getAccountId(), buildQueryParams(buildBundleIdList(entitlements)), request);
+ return uriBuilder.buildResponse(uriInfo, AccountResource.class, "getAccountBundles", account.getId(), buildQueryParams(bundleIds), request);
} else if (responseObject == ObjectType.BUNDLE) {
- return uriBuilder.buildResponse(uriInfo, BundleResource.class, "getBundle", entitlements.get(0).getBundleId(), request);
+ return uriBuilder.buildResponse(uriInfo, BundleResource.class, "getBundle", Iterables.getFirst(bundleIds, null), request);
} else {
throw new IllegalStateException("Unexpected input responseObject " + responseObject);
}
}
};
- final EntitlementCallCompletion<List<Entitlement>> callCompletionCreation = new EntitlementCallCompletion<List<Entitlement>>();
+ final EntitlementCallCompletion<List<UUID>> callCompletionCreation = new EntitlementCallCompletion<List<UUID>>();
return callCompletionCreation.withSynchronization(callback, timeoutSec, callCompletion, callContext);
}
-
-
private List<EntitlementSpecifier> buildEntitlementSpecifierList(final SubscriptionJson baseEntitlement, final Iterable<SubscriptionJson> addonEntitlements, final Currency currency) {
final List<EntitlementSpecifier> entitlementSpecifierList = new ArrayList<EntitlementSpecifier>();
@@ -478,17 +488,7 @@ public class SubscriptionResource extends JaxRsResourceBase {
};
}
- private List<String> buildBundleIdList(final List<Entitlement> entitlements) {
- List<String> result = new ArrayList<String>();
- for (Entitlement entitlement : entitlements) {
- if (!result.contains(entitlement.getBundleId().toString())) {
- result.add(entitlement.getBundleId().toString());
- }
- }
- return result;
- }
-
- private Map<String, String> buildQueryParams(final List<String> bundleIdList) {
+ private Map<String, String> buildQueryParams(final Iterable<String> bundleIdList) {
Map<String, String> queryParams = new HashMap<String, String>();
String value = "";
for (String bundleId : bundleIdList) {
diff --git a/junction/src/test/java/org/killbill/billing/junction/plumbing/billing/TestDefaultInternalBillingApi.java b/junction/src/test/java/org/killbill/billing/junction/plumbing/billing/TestDefaultInternalBillingApi.java
index f4a34ed..275aaa3 100644
--- a/junction/src/test/java/org/killbill/billing/junction/plumbing/billing/TestDefaultInternalBillingApi.java
+++ b/junction/src/test/java/org/killbill/billing/junction/plumbing/billing/TestDefaultInternalBillingApi.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
@@ -19,6 +19,7 @@
package org.killbill.billing.junction.plumbing.billing;
import java.util.List;
+import java.util.UUID;
import org.joda.time.DateTime;
import org.joda.time.LocalDate;
@@ -60,7 +61,8 @@ public class TestDefaultInternalBillingApi extends JunctionTestSuiteWithEmbedded
testListener.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK);
final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Shotgun", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null);
- final Entitlement entitlement = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final Entitlement entitlement = entitlementApi.getEntitlementForId(entitlementId, callContext);
final SubscriptionBase subscription = subscriptionInternalApi.getSubscriptionFromId(entitlement.getId(), internalCallContext);
assertListenerStatus();
@@ -205,7 +207,8 @@ public class TestDefaultInternalBillingApi extends JunctionTestSuiteWithEmbedded
testListener.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK);
final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Shotgun", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null);
- final Entitlement entitlement = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final UUID entitlementId = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, null, null, false, true, ImmutableList.<PluginProperty>of(), callContext);
+ final Entitlement entitlement = entitlementApi.getEntitlementForId(entitlementId, callContext);
final SubscriptionBase subscription = subscriptionInternalApi.getSubscriptionFromId(entitlement.getId(), internalCallContext);
assertListenerStatus();
pom.xml 2(+1 -1)
diff --git a/pom.xml b/pom.xml
index da317d0..06735c7 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.57</version>
+ <version>0.141.58</version>
</parent>
<artifactId>killbill</artifactId>
<version>0.19.10-SNAPSHOT</version>
diff --git a/subscription/src/main/java/org/killbill/billing/subscription/api/SubscriptionBaseApiService.java b/subscription/src/main/java/org/killbill/billing/subscription/api/SubscriptionBaseApiService.java
index 2740f09..a877800 100644
--- a/subscription/src/main/java/org/killbill/billing/subscription/api/SubscriptionBaseApiService.java
+++ b/subscription/src/main/java/org/killbill/billing/subscription/api/SubscriptionBaseApiService.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
@@ -36,18 +36,12 @@ import org.killbill.billing.catalog.api.PlanSpecifier;
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.SubscriptionBuilder;
import org.killbill.billing.subscription.events.SubscriptionBaseEvent;
import org.killbill.billing.util.callcontext.CallContext;
import org.killbill.billing.util.callcontext.TenantContext;
public interface SubscriptionBaseApiService {
- public DefaultSubscriptionBase createPlan(SubscriptionBuilder builder, Plan plan, PhaseType initialPhase,
- String realPriceList, DateTime effectiveDate,
- Catalog catalog, CallContext context)
- throws SubscriptionBaseApiException;
-
public List<SubscriptionBaseWithAddOns> createPlansWithAddOns(UUID accountId, Iterable<SubscriptionAndAddOnsSpecifier> subscriptionsAndAddOns, Catalog catalog, CallContext context)
throws SubscriptionBaseApiException;
@@ -98,13 +92,6 @@ public interface SubscriptionBaseApiService {
InternalTenantContext context)
throws CatalogApiException, SubscriptionBaseApiException;
- /*
- public List<SubscriptionBaseEvent> getEventsOnChangePlan(final DefaultSubscriptionBase subscription, final Plan newPlan,
- final String newPriceList, final DateTime effectiveDate,
- final boolean addCancellationAddOnForEventsIfRequired, final InternalTenantContext internalTenantContext) throws CatalogApiException, SubscriptionBaseApiException {
-
- */
-
public List<SubscriptionBaseEvent> getEventsOnChangePlan(DefaultSubscriptionBase subscription, Plan newPlan,
String newPriceList, DateTime effectiveDate,
boolean addCancellationAddOnForEventsIfRequired,
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 e5b22df..e6bdb7b 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
@@ -47,7 +47,6 @@ 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.ProductCategory;
-import org.killbill.billing.entitlement.api.BaseEntitlementWithAddOnsSpecifier;
import org.killbill.billing.entitlement.api.Entitlement.EntitlementState;
import org.killbill.billing.entitlement.api.EntitlementAOStatusDryRun;
import org.killbill.billing.entitlement.api.EntitlementAOStatusDryRun.DryRunChangeReason;
@@ -59,6 +58,7 @@ import org.killbill.billing.subscription.api.SubscriptionBase;
import org.killbill.billing.subscription.api.SubscriptionBaseApiService;
import org.killbill.billing.subscription.api.SubscriptionBaseInternalApi;
import org.killbill.billing.subscription.api.SubscriptionBaseWithAddOns;
+import org.killbill.billing.subscription.api.SubscriptionBaseWithAddOnsSpecifier;
import org.killbill.billing.subscription.api.user.DefaultEffectiveSubscriptionEvent;
import org.killbill.billing.subscription.api.user.DefaultSubscriptionBase;
import org.killbill.billing.subscription.api.user.DefaultSubscriptionBaseBundle;
@@ -79,6 +79,12 @@ import org.killbill.billing.subscription.events.bcd.BCDEventData;
import org.killbill.billing.subscription.exceptions.SubscriptionBaseError;
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;
+import org.killbill.billing.util.cache.Cachable.CacheType;
+import org.killbill.billing.util.cache.CacheController;
+import org.killbill.billing.util.cache.CacheControllerDispatcher;
+import org.killbill.billing.util.cache.CacheLoaderArgument;
import org.killbill.billing.util.callcontext.CallContext;
import org.killbill.billing.util.callcontext.InternalCallContextFactory;
import org.killbill.billing.util.callcontext.TenantContext;
@@ -107,6 +113,8 @@ public class DefaultSubscriptionInternalApi extends SubscriptionApiBase implemen
private final AddonUtils addonUtils;
private final InternalCallContextFactory internalCallContextFactory;
private final CatalogInternalApi catalogInternalApi;
+ private final CacheController<UUID, UUID> accountIdCacheController;
+ private final CacheController<UUID, UUID> bundleIdCacheController;
public static final Comparator<SubscriptionBase> SUBSCRIPTIONS_COMPARATOR = new Comparator<SubscriptionBase>() {
@@ -129,77 +137,27 @@ public class DefaultSubscriptionInternalApi extends SubscriptionApiBase implemen
final Clock clock,
final CatalogInternalApi catalogInternalApi,
final AddonUtils addonUtils,
+ final CacheControllerDispatcher cacheControllerDispatcher,
final InternalCallContextFactory internalCallContextFactory) {
super(dao, apiService, clock);
this.addonUtils = addonUtils;
this.internalCallContextFactory = internalCallContextFactory;
this.catalogInternalApi = catalogInternalApi;
- }
-
- @Override
- public SubscriptionBase createSubscription(final SubscriptionBaseBundle bundle,
- @Nullable final SubscriptionBase baseSubscription,
- final PlanPhaseSpecifier spec,
- final List<PlanPhasePriceOverride> overrides,
- final DateTime requestedDateWithMs,
- final boolean isMigrated,
- final InternalCallContext context) throws SubscriptionBaseApiException {
- try {
- if (bundle == null) {
- throw new SubscriptionBaseApiException(ErrorCode.SUB_CREATE_NO_BUNDLE, null);
- }
-
- final DateTime now = clock.getUTCNow();
- final DateTime effectiveDate = (requestedDateWithMs != null) ? DefaultClock.truncateMs(requestedDateWithMs) : now;
- /*
- if (requestedDate.isAfter(now)) {
- throw new SubscriptionBaseApiException(ErrorCode.SUB_INVALID_REQUESTED_DATE, now.toString(), requestedDate.toString());
- }
- */
-
- final CallContext callContext = internalCallContextFactory.createCallContext(context);
- final Catalog catalog = catalogInternalApi.getFullCatalog(true, true, context);
- final PlanPhasePriceOverridesWithCallContext overridesWithContext = new DefaultPlanPhasePriceOverridesWithCallContext(overrides, callContext);
-
- final Plan plan = catalog.createOrFindPlan(spec, overridesWithContext, effectiveDate);
- final PlanPhase phase = plan.getAllPhases()[0];
- if (phase == null) {
- throw new SubscriptionBaseError(String.format("No initial PlanPhase for Product %s, term %s and set %s does not exist in the catalog",
- spec.getProductName(), spec.getBillingPeriod().toString(), plan.getPriceListName()));
- }
-
- // verify the number of subscriptions (of the same kind) allowed per bundle
- if (ProductCategory.ADD_ON.toString().equalsIgnoreCase(plan.getProduct().getCategory().toString())) {
- if (plan.getPlansAllowedInBundle() != -1
- && plan.getPlansAllowedInBundle() > 0
- && addonUtils.countExistingAddOnsWithSamePlanName(getSubscriptionsForBundle(bundle.getId(), null, context), plan.getName())
- >= plan.getPlansAllowedInBundle()) {
- // a new ADD_ON subscription of the same plan can't be added because it has reached its limit by bundle
- throw new SubscriptionBaseApiException(ErrorCode.SUB_CREATE_AO_MAX_PLAN_ALLOWED_BY_BUNDLE, plan.getName());
- }
- }
-
- final DateTime bundleStartDate = getBundleStartDateWithSanity(bundle.getId(), baseSubscription, plan, effectiveDate, catalog, context);
- return apiService.createPlan(new SubscriptionBuilder()
- .setId(UUIDs.randomUUID())
- .setBundleId(bundle.getId())
- .setBundleExternalKey(bundle.getExternalKey())
- .setCategory(plan.getProduct().getCategory())
- .setBundleStartDate(bundleStartDate)
- .setAlignStartDate(effectiveDate)
- .setMigrated(isMigrated),
- plan, spec.getPhaseType(), plan.getPriceListName(), effectiveDate, catalog, callContext);
- } catch (final CatalogApiException e) {
- throw new SubscriptionBaseApiException(e);
- }
- }
-
- private List<SubscriptionSpecifier> verifyAndBuildSubscriptionSpecifiers(final UUID bundleId, final String externalKey, final Iterable<EntitlementSpecifier> entitlements, final boolean isMigrated, final InternalCallContext context, final DateTime now, final DateTime effectiveDate, final Catalog catalog, final CallContext callContext) throws SubscriptionBaseApiException, CatalogApiException {
+ this.accountIdCacheController = cacheControllerDispatcher.getCacheController(CacheType.ACCOUNT_ID_FROM_BUNDLE_ID);
+ this.bundleIdCacheController = cacheControllerDispatcher.getCacheController(CacheType.BUNDLE_ID_FROM_SUBSCRIPTION_ID);
+ }
+
+ private List<SubscriptionSpecifier> verifyAndBuildSubscriptionSpecifiers(final SubscriptionBaseBundle bundle,
+ @Nullable final EntitlementSpecifier baseOrStandalonePlanSpecifier,
+ final Iterable<EntitlementSpecifier> entitlements,
+ final boolean isMigrated,
+ final InternalCallContext context,
+ final DateTime now,
+ final DateTime effectiveDate,
+ final Catalog catalog,
+ final CallContext callContext) throws SubscriptionBaseApiException, CatalogApiException {
final List<SubscriptionSpecifier> subscriptions = new ArrayList<SubscriptionSpecifier>();
- final List<SubscriptionBase> subscriptionsForBundle = getSubscriptionsForBundle(bundleId, null, context);
-
for (final EntitlementSpecifier entitlement : entitlements) {
-
final PlanPhaseSpecifier spec = entitlement.getPlanPhaseSpecifier();
if (spec == null) {
// BP already exists
@@ -218,6 +176,8 @@ public class DefaultSubscriptionInternalApi extends SubscriptionApiBase implemen
// verify the number of subscriptions (of the same kind) allowed per bundle and the existing ones
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, context);
final int existingAddOnsWithSamePlanName = addonUtils.countExistingAddOnsWithSamePlanName(subscriptionsForBundle, plan.getName());
final int currentAddOnsWithSamePlanName = countCurrentAddOnsWithSamePlanName(entitlements, catalog, plan.getName(), effectiveDate, callContext);
if ((existingAddOnsWithSamePlanName + currentAddOnsWithSamePlanName) > plan.getPlansAllowedInBundle()) {
@@ -227,6 +187,14 @@ public class DefaultSubscriptionInternalApi extends SubscriptionApiBase implemen
}
}
+ final DateTime bundleStartDate;
+ if (baseOrStandalonePlanSpecifier != null) {
+ bundleStartDate = effectiveDate;
+ } else {
+ final SubscriptionBase baseSubscription = dao.getBaseSubscription(bundle.getId(), catalog, context);
+ bundleStartDate = getBundleStartDateWithSanity(bundle.getId(), baseSubscription, plan, effectiveDate, catalog, context);
+ }
+
final SubscriptionSpecifier subscription = new SubscriptionSpecifier();
subscription.setRealPriceList(plan.getPriceListName());
subscription.setEffectiveDate(effectiveDate);
@@ -235,10 +203,10 @@ public class DefaultSubscriptionInternalApi extends SubscriptionApiBase implemen
subscription.setInitialPhase(spec.getPhaseType());
subscription.setBuilder(new SubscriptionBuilder()
.setId(UUIDs.randomUUID())
- .setBundleId(bundleId)
- .setBundleExternalKey(externalKey)
+ .setBundleId(bundle.getId())
+ .setBundleExternalKey(bundle.getExternalKey())
.setCategory(plan.getProduct().getCategory())
- .setBundleStartDate(effectiveDate)
+ .setBundleStartDate(bundleStartDate)
.setAlignStartDate(effectiveDate)
.setMigrated(isMigrated));
@@ -247,14 +215,17 @@ public class DefaultSubscriptionInternalApi extends SubscriptionApiBase implemen
return subscriptions;
}
- private boolean sanityAndReorderBPOrStandaloneSpecFirst(final Catalog catalog, final BaseEntitlementWithAddOnsSpecifier entitlementWithAddOnsSpecifier, final DateTime effectiveDate, final List<EntitlementSpecifier> outputEntitlementSpecifier) throws SubscriptionBaseApiException {
-
+ private EntitlementSpecifier sanityAndReorderBPOrStandaloneSpecFirst(final Catalog catalog,
+ final SubscriptionBaseWithAddOnsSpecifier subscriptionBaseWithAddOnsSpecifier,
+ final DateTime effectiveDate,
+ final Collection<EntitlementSpecifier> outputEntitlementSpecifier) throws SubscriptionBaseApiException {
EntitlementSpecifier baseOrStandalonePlanSpecifier = null;
- final List<EntitlementSpecifier> addOnSpecifiers = new ArrayList<EntitlementSpecifier>();
+ final Collection<EntitlementSpecifier> addOnSpecifiers = new ArrayList<EntitlementSpecifier>();
try {
- for (final EntitlementSpecifier cur : entitlementWithAddOnsSpecifier.getEntitlementSpecifier()) {
- final Plan inputPlan = catalog.createOrFindPlan(cur.getPlanPhaseSpecifier(), null, effectiveDate);
- final boolean isBaseOrStandaloneSpecifier = inputPlan.getProduct().getCategory() == ProductCategory.BASE || inputPlan.getProduct().getCategory() == ProductCategory.STANDALONE;
+ for (final EntitlementSpecifier cur : subscriptionBaseWithAddOnsSpecifier.getEntitlementSpecifiers()) {
+ final boolean isBase = isBaseSpecifier(catalog, effectiveDate, cur);
+ final boolean isStandalone = isStandaloneSpecifier(catalog, effectiveDate, cur);
+ final boolean isBaseOrStandaloneSpecifier = isBase || isStandalone;
if (isBaseOrStandaloneSpecifier) {
if (baseOrStandalonePlanSpecifier == null) {
baseOrStandalonePlanSpecifier = cur;
@@ -273,54 +244,97 @@ public class DefaultSubscriptionInternalApi extends SubscriptionApiBase implemen
outputEntitlementSpecifier.add(baseOrStandalonePlanSpecifier);
}
outputEntitlementSpecifier.addAll(addOnSpecifiers);
- return baseOrStandalonePlanSpecifier != null;
+ return baseOrStandalonePlanSpecifier;
+ }
+
+ private boolean isBaseSpecifier(final Catalog catalog, final DateTime effectiveDate, final EntitlementSpecifier cur) throws CatalogApiException {
+ final Plan inputPlan = catalog.createOrFindPlan(cur.getPlanPhaseSpecifier(), null, effectiveDate);
+ return inputPlan.getProduct().getCategory() == ProductCategory.BASE;
+ }
+
+ private boolean isStandaloneSpecifier(final Catalog catalog, final DateTime effectiveDate, final EntitlementSpecifier cur) throws CatalogApiException {
+ final Plan inputPlan = catalog.createOrFindPlan(cur.getPlanPhaseSpecifier(), null, effectiveDate);
+ return inputPlan.getProduct().getCategory() == ProductCategory.STANDALONE;
}
@Override
- public List<SubscriptionBaseWithAddOns> createBaseSubscriptionsWithAddOns(final UUID accountId, final Iterable<BaseEntitlementWithAddOnsSpecifier> baseEntitlementWithAddOnsSpecifier, final boolean renameCancelledBundleIfExist, final InternalCallContext context) throws SubscriptionBaseApiException {
+ public List<SubscriptionBaseWithAddOns> createBaseSubscriptionsWithAddOns(final Iterable<SubscriptionBaseWithAddOnsSpecifier> subscriptionWithAddOnsSpecifiers, final boolean renameCancelledBundleIfExist, final InternalCallContext context) throws SubscriptionBaseApiException {
try {
final Catalog catalog = catalogInternalApi.getFullCatalog(true, true, context);
final CallContext callContext = internalCallContextFactory.createCallContext(context);
+ final UUID accountId = callContext.getAccountId();
final DateTime now = clock.getUTCNow();
final Collection<SubscriptionAndAddOnsSpecifier> subscriptionAndAddOns = new ArrayList<SubscriptionAndAddOnsSpecifier>();
- for (final BaseEntitlementWithAddOnsSpecifier entitlementWithAddOnsSpecifier : baseEntitlementWithAddOnsSpecifier) {
- final DateTime effectiveDate = (entitlementWithAddOnsSpecifier.getBillingEffectiveDate() != null) ?
- context.toUTCDateTime(entitlementWithAddOnsSpecifier.getBillingEffectiveDate()) : now;
-
- final List<EntitlementSpecifier> reorderedSpecifiers = new ArrayList<EntitlementSpecifier>();
- final boolean isBaseOrStandaloneSpecifierExists = sanityAndReorderBPOrStandaloneSpecFirst(catalog, entitlementWithAddOnsSpecifier, effectiveDate, reorderedSpecifiers);
-
- final SubscriptionBaseBundle bundle;
- if (isBaseOrStandaloneSpecifierExists) {
- bundle = createBundleForAccount(accountId, entitlementWithAddOnsSpecifier.getExternalKey(), renameCancelledBundleIfExist, context);
- } else {
- final List<SubscriptionBaseBundle> existingBundles = dao.getSubscriptionBundlesForKey(entitlementWithAddOnsSpecifier.getExternalKey(), context);
+ for (final SubscriptionBaseWithAddOnsSpecifier subscriptionBaseWithAddOnsSpecifier : subscriptionWithAddOnsSpecifiers) {
+ final DateTime billingRequestedDateRaw = subscriptionBaseWithAddOnsSpecifier.getBillingEffectiveDate() != null ? subscriptionBaseWithAddOnsSpecifier.getBillingEffectiveDate() : now;
+
+ final Collection<EntitlementSpecifier> reorderedSpecifiers = new ArrayList<EntitlementSpecifier>();
+ // Note: billingRequestedDateRaw might not be accurate here (add-on with a too early date passed)?
+ final EntitlementSpecifier baseOrStandalonePlanSpecifier = sanityAndReorderBPOrStandaloneSpecFirst(catalog, subscriptionBaseWithAddOnsSpecifier, billingRequestedDateRaw, reorderedSpecifiers);
+
+ DateTime billingRequestedDate = billingRequestedDateRaw;
+ SubscriptionBaseBundle bundle = null;
+ if (subscriptionBaseWithAddOnsSpecifier.getBundleId() != null) {
+ bundle = dao.getSubscriptionBundleFromId(subscriptionBaseWithAddOnsSpecifier.getBundleId(), context);
+ if (bundle == null ||
+ (subscriptionBaseWithAddOnsSpecifier.getBundleExternalKey() != null && !subscriptionBaseWithAddOnsSpecifier.getBundleExternalKey().equals(bundle.getExternalKey()))) {
+ throw new SubscriptionBaseApiException(ErrorCode.SUB_CREATE_INVALID_ENTITLEMENT_SPECIFIER);
+ }
+ } else if (subscriptionBaseWithAddOnsSpecifier.getBundleExternalKey() != null &&
+ baseOrStandalonePlanSpecifier == null) { // Skip the expensive checks if we are about to create the bundle (validation will be done in SubscriptionDao#createSubscriptionBundle)
+ final List<SubscriptionBaseBundle> existingBundles = dao.getSubscriptionBundlesForKey(subscriptionBaseWithAddOnsSpecifier.getBundleExternalKey(), context);
final SubscriptionBaseBundle tmp = getActiveBundleForKeyNotException(existingBundles, dao, clock, catalog, context);
if (tmp == null) {
- throw new SubscriptionBaseApiException(ErrorCode.SUB_CREATE_NO_BP, entitlementWithAddOnsSpecifier.getExternalKey());
+ throw new SubscriptionBaseApiException(ErrorCode.SUB_CREATE_NO_BP, subscriptionBaseWithAddOnsSpecifier.getBundleExternalKey());
} else if (!tmp.getAccountId().equals(accountId)) {
- throw new SubscriptionBaseApiException(ErrorCode.SUB_CREATE_ACTIVE_BUNDLE_KEY_EXISTS, entitlementWithAddOnsSpecifier.getExternalKey());
+ throw new SubscriptionBaseApiException(ErrorCode.SUB_CREATE_ACTIVE_BUNDLE_KEY_EXISTS, subscriptionBaseWithAddOnsSpecifier.getBundleExternalKey());
} else {
bundle = tmp;
}
}
+ SubscriptionBase baseSubscription = null;
+ if (bundle != null) {
+ baseSubscription = dao.getBaseSubscription(bundle.getId(), catalog, context);
+ if (baseSubscription != null) {
+ final DateTime baseSubscriptionStartDate = getBaseSubscription(bundle.getId(), context).getStartDate();
+ billingRequestedDate = billingRequestedDateRaw.isBefore(baseSubscriptionStartDate) ? baseSubscriptionStartDate : billingRequestedDateRaw;
+ }
+ }
+
+ if (bundle == null && baseOrStandalonePlanSpecifier != null) {
+ bundle = createBundleForAccount(accountId,
+ subscriptionBaseWithAddOnsSpecifier.getBundleExternalKey(),
+ renameCancelledBundleIfExist,
+ context);
+ } else if (bundle != null && baseSubscription != null && baseOrStandalonePlanSpecifier != null && isBaseSpecifier(catalog, billingRequestedDateRaw, baseOrStandalonePlanSpecifier)) {
+ throw new SubscriptionBaseApiException(ErrorCode.SUB_CREATE_BP_EXISTS, bundle.getExternalKey());
+ } else if (bundle == null) {
+ throw new SubscriptionBaseApiException(ErrorCode.SUB_CREATE_INVALID_ENTITLEMENT_SPECIFIER);
+ }
+
final SubscriptionAndAddOnsSpecifier subscriptionAndAddOnsSpecifier = new SubscriptionAndAddOnsSpecifier(bundle,
- effectiveDate,
- verifyAndBuildSubscriptionSpecifiers(bundle.getId(),
- bundle.getExternalKey(),
+ billingRequestedDate,
+ verifyAndBuildSubscriptionSpecifiers(bundle,
+ baseOrStandalonePlanSpecifier,
reorderedSpecifiers,
- entitlementWithAddOnsSpecifier.isMigrated(),
+ subscriptionBaseWithAddOnsSpecifier.isMigrated(),
context,
now,
- effectiveDate,
+ billingRequestedDate,
catalog,
callContext));
subscriptionAndAddOns.add(subscriptionAndAddOnsSpecifier);
}
- return apiService.createPlansWithAddOns(accountId, subscriptionAndAddOns, catalog, callContext);
+ final List<SubscriptionBaseWithAddOns> subscriptionBaseWithAddOns = apiService.createPlansWithAddOns(accountId, subscriptionAndAddOns, catalog, callContext);
+ for (final SubscriptionBaseWithAddOns subscriptionBaseWithAO : subscriptionBaseWithAddOns) {
+ for (final SubscriptionBase subscriptionBase : subscriptionBaseWithAO.getSubscriptionBaseList()) {
+ bundleIdCacheController.putIfAbsent(subscriptionBase.getId(), subscriptionBaseWithAO.getBundle().getId());
+ }
+ }
+ return subscriptionBaseWithAddOns;
} catch (final CatalogApiException e) {
throw new SubscriptionBaseApiException(e);
}
@@ -371,9 +385,9 @@ public class DefaultSubscriptionInternalApi extends SubscriptionApiBase implemen
}
+ @VisibleForTesting
@Override
public SubscriptionBaseBundle createBundleForAccount(final UUID accountId, final String bundleKey, final boolean renameCancelledBundleIfExist, final InternalCallContext context) throws SubscriptionBaseApiException {
-
final DateTime now = clock.getUTCNow();
final DefaultSubscriptionBaseBundle bundle = new DefaultSubscriptionBaseBundle(bundleKey, accountId, now, now, now, now);
if (null != bundleKey && bundleKey.length() > 255) {
@@ -381,7 +395,9 @@ public class DefaultSubscriptionInternalApi extends SubscriptionApiBase implemen
}
try {
final Catalog catalog = catalogInternalApi.getFullCatalog(true, true, context);
- return dao.createSubscriptionBundle(bundle, catalog, renameCancelledBundleIfExist, context);
+ final SubscriptionBaseBundle subscriptionBundle = dao.createSubscriptionBundle(bundle, catalog, renameCancelledBundleIfExist, context);
+ accountIdCacheController.putIfAbsent(bundle.getId(), accountId);
+ return subscriptionBundle;
} catch (final CatalogApiException e) {
throw new SubscriptionBaseApiException(e);
}
@@ -547,11 +563,6 @@ public class DefaultSubscriptionInternalApi extends SubscriptionApiBase implemen
}
@Override
- public UUID getAccountIdFromSubscriptionId(final UUID subscriptionId, final InternalTenantContext context) throws SubscriptionBaseApiException {
- return dao.getAccountIdFromSubscriptionId(subscriptionId, context);
- }
-
- @Override
public void setChargedThroughDate(final UUID subscriptionId, final DateTime chargedThruDate, final InternalCallContext context) throws SubscriptionBaseApiException {
try {
@@ -793,6 +804,67 @@ public class DefaultSubscriptionInternalApi extends SubscriptionApiBase implemen
}
}
+ @Override
+ public UUID getAccountIdFromBundleId(final UUID bundleId, final InternalTenantContext context) throws SubscriptionBaseApiException {
+ final CacheLoaderArgument arg = createAccountIdFromBundleIdCacheLoaderArgument(context);
+ return accountIdCacheController.get(bundleId, arg);
+ }
+
+ @Override
+ public UUID getBundleIdFromSubscriptionId(final UUID subscriptionId, final InternalTenantContext context) throws SubscriptionBaseApiException {
+ final CacheLoaderArgument arg = createBundleIdFromSubscriptionIdCacheLoaderArgument(context);
+ return bundleIdCacheController.get(subscriptionId, arg);
+ }
+
+ @Override
+ public UUID getAccountIdFromSubscriptionId(final UUID subscriptionId, final InternalTenantContext context) throws SubscriptionBaseApiException {
+ final UUID bundleId = getBundleIdFromSubscriptionId(subscriptionId, context);
+ if (bundleId == null) {
+ throw new SubscriptionBaseApiException(ErrorCode.SUB_GET_NO_BUNDLE_FOR_SUBSCRIPTION, subscriptionId);
+ }
+ final UUID accountId = getAccountIdFromBundleId(bundleId, context);
+ if (accountId == null) {
+ throw new SubscriptionBaseApiException(ErrorCode.SUB_GET_INVALID_BUNDLE_ID, bundleId);
+ }
+ return accountId;
+ }
+
+ private CacheLoaderArgument createAccountIdFromBundleIdCacheLoaderArgument(final InternalTenantContext internalTenantContext) {
+ final AccountIdFromBundleIdCacheLoader.LoaderCallback loaderCallback = new AccountIdFromBundleIdCacheLoader.LoaderCallback() {
+ public UUID loadAccountId(final UUID bundleId, final InternalTenantContext internalTenantContext) {
+ final SubscriptionBaseBundle bundle;
+ try {
+ bundle = getBundleFromId(bundleId, internalTenantContext);
+ } catch (final SubscriptionBaseApiException e) {
+ log.warn("Unable to retrieve bundle for id='{}'", bundleId);
+ return null;
+ }
+ return bundle.getAccountId();
+ }
+ };
+
+ final Object[] args = {loaderCallback};
+ return new CacheLoaderArgument(null, args, internalTenantContext);
+ }
+
+ private CacheLoaderArgument createBundleIdFromSubscriptionIdCacheLoaderArgument(final InternalTenantContext internalTenantContext) {
+ final BundleIdFromSubscriptionIdCacheLoader.LoaderCallback loaderCallback = new BundleIdFromSubscriptionIdCacheLoader.LoaderCallback() {
+ public UUID loadBundleId(final UUID subscriptionId, final InternalTenantContext internalTenantContext) {
+ final SubscriptionBase subscriptionBase;
+ try {
+ subscriptionBase = getSubscriptionFromId(subscriptionId, internalTenantContext);
+ } catch (final SubscriptionBaseApiException e) {
+ log.warn("Unable to retrieve subscription for id='{}'", subscriptionId);
+ return null;
+ }
+ return subscriptionBase.getBundleId();
+ }
+ };
+
+ final Object[] args = {loaderCallback};
+ return new CacheLoaderArgument(null, args, internalTenantContext);
+ }
+
@VisibleForTesting
DateTime getEffectiveDateForNewBCD(final int bcd, @Nullable final LocalDate effectiveFromDate, final InternalCallContext internalCallContext) {
if (internalCallContext.getAccountRecordId() == null) {
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 1e1fc4e..27b31f3 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
@@ -76,8 +76,10 @@ import org.killbill.clock.Clock;
import org.killbill.clock.DefaultClock;
import com.google.common.base.Preconditions;
+import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ListMultimap;
import com.google.inject.Inject;
public class DefaultSubscriptionBaseApiService implements SubscriptionBaseApiService {
@@ -102,26 +104,6 @@ public class DefaultSubscriptionBaseApiService implements SubscriptionBaseApiSer
}
@Override
- public DefaultSubscriptionBase createPlan(final SubscriptionBuilder builder, final Plan plan, final PhaseType initialPhase,
- final String realPriceList, final DateTime effectiveDate, final Catalog fullCatalog,
- final CallContext context) throws SubscriptionBaseApiException {
- final DefaultSubscriptionBase subscription = new DefaultSubscriptionBase(builder, this, clock);
-
- final InternalCallContext internalCallContext = createCallContextFromBundleId(subscription.getBundleId(), context);
-
- try {
-
- final List<SubscriptionBaseEvent> events = getEventsOnCreation(subscription.getId(), subscription.getAlignStartDate(), subscription.getBundleStartDate(),
- plan, initialPhase, realPriceList, effectiveDate, fullCatalog, internalCallContext);
- final List<SubscriptionBaseEvent> createdEvents = dao.createSubscription(subscription, events, fullCatalog, internalCallContext);
- subscription.rebuildTransitions(createdEvents, fullCatalog);
- return subscription;
- } catch (final CatalogApiException e) {
- throw new SubscriptionBaseApiException(e);
- }
- }
-
- @Override
public List<SubscriptionBaseWithAddOns> createPlansWithAddOns(final UUID accountId, final Iterable<SubscriptionAndAddOnsSpecifier> subscriptionsAndAddOns, final Catalog fullCatalog, final CallContext context) throws SubscriptionBaseApiException {
final Map<UUID, List<SubscriptionBaseEvent>> eventsMap = new HashMap<UUID, List<SubscriptionBaseEvent>>();
final Collection<List<SubscriptionBase>> subscriptionBaseAndAddOnsList = new ArrayList<List<SubscriptionBase>>();
@@ -136,16 +118,19 @@ public class DefaultSubscriptionBaseApiService implements SubscriptionBaseApiSer
subscriptionBaseAndAddOnsList.add(subscriptionBaseList);
final SubscriptionBaseWithAddOns subscriptionBaseWithAddOns = new DefaultSubscriptionBaseWithAddOns(subscriptionAndAddOns.getBundle(),
- subscriptionBaseList,
- subscriptionAndAddOns.getEffectiveDate());
+ subscriptionBaseList);
allSubscriptions.add(subscriptionBaseWithAddOns);
}
- dao.createSubscriptionsWithAddOns(allSubscriptions, eventsMap, fullCatalog, internalCallContext);
+ final List<SubscriptionBaseEvent> events = dao.createSubscriptionsWithAddOns(allSubscriptions, eventsMap, fullCatalog, internalCallContext);
+ final ListMultimap<UUID, SubscriptionBaseEvent> eventsBySubscription = ArrayListMultimap.<UUID, SubscriptionBaseEvent>create();
+ for (final SubscriptionBaseEvent event : events) {
+ eventsBySubscription.put(event.getSubscriptionId(), event);
+ }
for (final List<SubscriptionBase> subscriptions : subscriptionBaseAndAddOnsList) {
for (final SubscriptionBase input : subscriptions) {
- ((DefaultSubscriptionBase) input).rebuildTransitions(dao.getEventsForSubscription(input.getId(), internalCallContext), fullCatalog);
+ ((DefaultSubscriptionBase) input).rebuildTransitions(eventsBySubscription.get(input.getId()), fullCatalog);
}
}
return allSubscriptions;
diff --git a/subscription/src/main/java/org/killbill/billing/subscription/api/user/DefaultSubscriptionBaseWithAddOns.java b/subscription/src/main/java/org/killbill/billing/subscription/api/user/DefaultSubscriptionBaseWithAddOns.java
index c2cbbe7..0530a72 100644
--- a/subscription/src/main/java/org/killbill/billing/subscription/api/user/DefaultSubscriptionBaseWithAddOns.java
+++ b/subscription/src/main/java/org/killbill/billing/subscription/api/user/DefaultSubscriptionBaseWithAddOns.java
@@ -19,24 +19,17 @@ package org.killbill.billing.subscription.api.user;
import java.util.List;
-import org.joda.time.DateTime;
import org.killbill.billing.subscription.api.SubscriptionBase;
import org.killbill.billing.subscription.api.SubscriptionBaseWithAddOns;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
public class DefaultSubscriptionBaseWithAddOns implements SubscriptionBaseWithAddOns {
- private static final Logger log = LoggerFactory.getLogger(DefaultSubscriptionBaseWithAddOns.class);
-
private final SubscriptionBaseBundle bundle;
private final List<SubscriptionBase> subscriptionBaseList;
- private final DateTime effectiveDate;
- public DefaultSubscriptionBaseWithAddOns(final SubscriptionBaseBundle bundle, final List<SubscriptionBase> subscriptionBaseList, final DateTime effectiveDate) {
+ public DefaultSubscriptionBaseWithAddOns(final SubscriptionBaseBundle bundle, final List<SubscriptionBase> subscriptionBaseList) {
this.bundle = bundle;
this.subscriptionBaseList = subscriptionBaseList;
- this.effectiveDate = effectiveDate;
}
@Override
@@ -48,8 +41,4 @@ public class DefaultSubscriptionBaseWithAddOns implements SubscriptionBaseWithAd
public List<SubscriptionBase> getSubscriptionBaseList() {
return subscriptionBaseList;
}
-
- public DateTime getEffectiveDate() {
- return effectiveDate;
- }
}
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 b88eb57..587e1b7 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
@@ -128,9 +128,9 @@ public class AddonUtils {
return false;
}
- public int countExistingAddOnsWithSamePlanName(final List<SubscriptionBase> subscriptionsForBundle, final String planName) {
+ public int countExistingAddOnsWithSamePlanName(final Iterable<SubscriptionBase> subscriptionsForBundle, final String planName) {
int countExistingAddOns = 0;
- for (SubscriptionBase subscription : subscriptionsForBundle) {
+ for (final SubscriptionBase subscription : subscriptionsForBundle) {
if (subscription.getCurrentPlan().getName().equalsIgnoreCase(planName)
&& subscription.getLastActiveProduct().getCategory() != null
&& ProductCategory.ADD_ON.equals(subscription.getLastActiveProduct().getCategory())) {
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 d0c740e..1c11dae 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
@@ -343,34 +343,6 @@ public class DefaultSubscriptionDao extends EntityDaoBase<SubscriptionBundleMode
}
@Override
- public UUID getAccountIdFromSubscriptionId(final UUID subscriptionId, final InternalTenantContext context) {
-
- return transactionalSqlDao.execute(true, new EntitySqlDaoTransactionWrapper<UUID>() {
- @Override
- public UUID inTransaction(final EntitySqlDaoWrapperFactory entitySqlDaoWrapperFactory) throws Exception {
- final SubscriptionModelDao subscriptionModel = entitySqlDaoWrapperFactory.become(SubscriptionSqlDao.class).getById(subscriptionId.toString(), context);
- if (subscriptionModel == null) {
- log.warn(String.format(ErrorCode.SUB_INVALID_SUBSCRIPTION_ID.getFormat(), subscriptionId.toString()));
- return null;
- }
-
- final UUID bundleId = subscriptionModel.getBundleId();
- if (bundleId == null) {
- log.warn(String.format(ErrorCode.SUB_GET_NO_BUNDLE_FOR_SUBSCRIPTION.getFormat(), subscriptionId.toString()));
- return null;
- }
-
- final SubscriptionBundleModelDao bundleModel = entitySqlDaoWrapperFactory.become(BundleSqlDao.class).getById(bundleId.toString(), context);
- if (bundleModel == null) {
- log.warn(String.format(ErrorCode.SUB_GET_INVALID_BUNDLE_ID.getFormat(), bundleId.toString()));
- return null;
- }
- return bundleModel.getAccountId();
- }
- });
- }
-
- @Override
public SubscriptionBase getBaseSubscription(final UUID bundleId, final Catalog catalog, final InternalTenantContext context) throws CatalogApiException {
return getBaseSubscription(bundleId, true, catalog, context);
}
@@ -550,40 +522,14 @@ public class DefaultSubscriptionDao extends EntityDaoBase<SubscriptionBundleMode
}
@Override
- public final List<SubscriptionBaseEvent> createSubscription(final DefaultSubscriptionBase subscription, final List<SubscriptionBaseEvent> initialEvents, final Catalog catalog, final InternalCallContext context) {
+ public List<SubscriptionBaseEvent> createSubscriptionsWithAddOns(final List<SubscriptionBaseWithAddOns> subscriptions, final Map<UUID, List<SubscriptionBaseEvent>> initialEventsMap, final Catalog catalog, final InternalCallContext context) {
return transactionalSqlDao.execute(false, new EntitySqlDaoTransactionWrapper<List<SubscriptionBaseEvent>>() {
@Override
public List<SubscriptionBaseEvent> inTransaction(final EntitySqlDaoWrapperFactory entitySqlDaoWrapperFactory) throws Exception {
final SubscriptionSqlDao transactional = entitySqlDaoWrapperFactory.become(SubscriptionSqlDao.class);
- createAndRefresh(transactional, new SubscriptionModelDao(subscription), context);
-
- final List<SubscriptionEventModelDao> createdEvents = new LinkedList<SubscriptionEventModelDao>();
- final SubscriptionEventSqlDao eventsDaoFromSameTransaction = entitySqlDaoWrapperFactory.become(SubscriptionEventSqlDao.class);
- for (final SubscriptionBaseEvent cur : initialEvents) {
- createdEvents.add(createAndRefresh(eventsDaoFromSameTransaction, new SubscriptionEventModelDao(cur), context));
-
- final boolean isBusEvent = cur.getEffectiveDate().compareTo(clock.getUTCNow()) <= 0 && (cur.getType() == EventType.API_USER);
- recordBusOrFutureNotificationFromTransaction(subscription, cur, entitySqlDaoWrapperFactory, isBusEvent, 0, catalog, context);
-
- }
- // Notify the Bus of the latest requested change, if needed
- if (!initialEvents.isEmpty()) {
- notifyBusOfRequestedChange(entitySqlDaoWrapperFactory, subscription, initialEvents.get(initialEvents.size() - 1), SubscriptionBaseTransitionType.CREATE, context);
- }
-
- return toSubscriptionBaseEvents(createdEvents);
- }
- });
- }
-
- @Override
- public void createSubscriptionsWithAddOns(final List<SubscriptionBaseWithAddOns> subscriptions, final Map<UUID, List<SubscriptionBaseEvent>> initialEventsMap, final Catalog catalog, final InternalCallContext context) {
- transactionalSqlDao.execute(false, new EntitySqlDaoTransactionWrapper<Void>() {
- @Override
- public Void inTransaction(final EntitySqlDaoWrapperFactory entitySqlDaoWrapperFactory) throws Exception {
- final SubscriptionSqlDao transactional = entitySqlDaoWrapperFactory.become(SubscriptionSqlDao.class);
final SubscriptionEventSqlDao eventsDaoFromSameTransaction = entitySqlDaoWrapperFactory.become(SubscriptionEventSqlDao.class);
+ final List<SubscriptionEventModelDao> createdEvents = new LinkedList<SubscriptionEventModelDao>();
for (final SubscriptionBaseWithAddOns subscription : subscriptions) {
for (final SubscriptionBase subscriptionBase : subscription.getSubscriptionBaseList()) {
// Safe cast
@@ -592,7 +538,7 @@ public class DefaultSubscriptionDao extends EntityDaoBase<SubscriptionBundleMode
final List<SubscriptionBaseEvent> initialEvents = initialEventsMap.get(defaultSubscriptionBase.getId());
for (final SubscriptionBaseEvent cur : initialEvents) {
- createAndRefresh(eventsDaoFromSameTransaction, new SubscriptionEventModelDao(cur), context);
+ createdEvents.add(createAndRefresh(eventsDaoFromSameTransaction, new SubscriptionEventModelDao(cur), context));
final boolean isBusEvent = cur.getEffectiveDate().compareTo(clock.getUTCNow()) <= 0 && (cur.getType() == EventType.API_USER);
recordBusOrFutureNotificationFromTransaction(defaultSubscriptionBase, cur, entitySqlDaoWrapperFactory, isBusEvent, 0, catalog, context);
@@ -604,7 +550,7 @@ public class DefaultSubscriptionDao extends EntityDaoBase<SubscriptionBundleMode
}
}
}
- return null;
+ return toSubscriptionBaseEvents(createdEvents);
}
});
}
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 5c623ee..3e6dd6c 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
@@ -59,9 +59,6 @@ public interface SubscriptionDao extends EntityDao<SubscriptionBundleModelDao, S
public SubscriptionBase getSubscriptionFromId(UUID subscriptionId, final Catalog catalog, InternalTenantContext context) throws CatalogApiException;
- // ACCOUNT retrieval
- public UUID getAccountIdFromSubscriptionId(UUID subscriptionId, InternalTenantContext context);
-
// SubscriptionBase retrieval
public SubscriptionBase getBaseSubscription(UUID bundleId, final Catalog catalog, InternalTenantContext context) throws CatalogApiException;
@@ -82,9 +79,8 @@ public interface SubscriptionDao extends EntityDao<SubscriptionBundleModelDao, S
public List<SubscriptionBaseEvent> getPendingEventsForSubscription(UUID subscriptionId, InternalTenantContext context);
// SubscriptionBase creation, cancellation, changePlanWithRequestedDate apis
- public List<SubscriptionBaseEvent> createSubscription(DefaultSubscriptionBase subscription, List<SubscriptionBaseEvent> initialEvents, final Catalog catalog, InternalCallContext context);
- public void createSubscriptionsWithAddOns(List<SubscriptionBaseWithAddOns> subscriptions, Map<UUID, List<SubscriptionBaseEvent>> initialEventsMap, final Catalog catalog, InternalCallContext context);
+ public List<SubscriptionBaseEvent> createSubscriptionsWithAddOns(List<SubscriptionBaseWithAddOns> subscriptions, Map<UUID, List<SubscriptionBaseEvent>> initialEventsMap, final Catalog catalog, InternalCallContext context);
public void cancelSubscriptionsOnBasePlanEvent(DefaultSubscriptionBase subscription, SubscriptionBaseEvent event, List<DefaultSubscriptionBase> subscriptions, List<SubscriptionBaseEvent> cancelEvents, final Catalog catalog, InternalCallContext context);
diff --git a/subscription/src/main/java/org/killbill/billing/subscription/engine/dao/SubscriptionEventSqlDao.java b/subscription/src/main/java/org/killbill/billing/subscription/engine/dao/SubscriptionEventSqlDao.java
index 0e195db..be4ddd1 100644
--- a/subscription/src/main/java/org/killbill/billing/subscription/engine/dao/SubscriptionEventSqlDao.java
+++ b/subscription/src/main/java/org/killbill/billing/subscription/engine/dao/SubscriptionEventSqlDao.java
@@ -1,7 +1,9 @@
/*
* Copyright 2010-2013 Ning, Inc.
+ * Copyright 2014-2018 Groupon, Inc
+ * Copyright 2014-2018 The Billing Project, LLC
*
- * Ning licenses this file to you under the Apache License, version 2.0
+ * 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
* License. You may obtain a copy of the License at:
*
@@ -26,9 +28,9 @@ import org.killbill.billing.subscription.events.SubscriptionBaseEvent;
import org.killbill.billing.util.audit.ChangeType;
import org.killbill.billing.util.entity.dao.Audited;
import org.killbill.billing.util.entity.dao.EntitySqlDao;
+import org.killbill.commons.jdbi.binder.SmartBindBean;
import org.killbill.commons.jdbi.template.KillBillSqlDaoStringTemplate;
import org.skife.jdbi.v2.sqlobject.Bind;
-import org.killbill.commons.jdbi.binder.SmartBindBean;
import org.skife.jdbi.v2.sqlobject.SqlQuery;
import org.skife.jdbi.v2.sqlobject.SqlUpdate;
@@ -53,7 +55,4 @@ public interface SubscriptionEventSqlDao extends EntitySqlDao<SubscriptionEventM
@SqlQuery
public List<SubscriptionEventModelDao> getActiveEventsForSubscription(@Bind("subscriptionId") String subscriptionId,
@SmartBindBean final InternalTenantContext context);
-
- @SqlQuery
- public List<SubscriptionEventModelDao> getFutureActiveEventsForAccount(@Bind("now") Date now, @SmartBindBean final InternalTenantContext context);
}
diff --git a/subscription/src/main/resources/org/killbill/billing/subscription/engine/dao/SubscriptionEventSqlDao.sql.stg b/subscription/src/main/resources/org/killbill/billing/subscription/engine/dao/SubscriptionEventSqlDao.sql.stg
index 94d407f..b8399da 100644
--- a/subscription/src/main/resources/org/killbill/billing/subscription/engine/dao/SubscriptionEventSqlDao.sql.stg
+++ b/subscription/src/main/resources/org/killbill/billing/subscription/engine/dao/SubscriptionEventSqlDao.sql.stg
@@ -12,7 +12,6 @@ defaultOrderBy(prefix) ::= <<
order by <prefix>effective_date ASC, <recordIdField(prefix)> ASC
>>
-
tableFields(prefix) ::= <<
<prefix> event_type
, <prefix> user_type
@@ -96,17 +95,5 @@ and is_active = true
;
>>
-getFutureActiveEventsForAccount() ::= <<
-select <allTableFields("")>
-, record_id as total_ordering
-from <tableName()>
-where
-account_record_id = :accountRecordId
-and is_active = true
-and effective_date > :now
-<AND_CHECK_TENANT("")>
-<defaultOrderBy("")>
-;
->>
diff --git a/subscription/src/test/java/org/killbill/billing/subscription/api/user/TestSubscriptionHelper.java b/subscription/src/test/java/org/killbill/billing/subscription/api/user/TestSubscriptionHelper.java
index 9c67ec3..87a882a 100644
--- a/subscription/src/test/java/org/killbill/billing/subscription/api/user/TestSubscriptionHelper.java
+++ b/subscription/src/test/java/org/killbill/billing/subscription/api/user/TestSubscriptionHelper.java
@@ -1,7 +1,7 @@
/*
* Copyright 2010-2013 Ning, Inc.
- * Copyright 2014-2015 Groupon, Inc
- * Copyright 2014-2015 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
@@ -28,7 +28,7 @@ import javax.inject.Inject;
import org.joda.time.DateTime;
import org.joda.time.LocalDate;
import org.joda.time.Period;
-import org.killbill.billing.account.api.AccountUserApi;
+import org.killbill.billing.ObjectType;
import org.killbill.billing.api.TestApiListener;
import org.killbill.billing.api.TestApiListener.NextEvent;
import org.killbill.billing.callcontext.InternalCallContext;
@@ -38,23 +38,28 @@ import org.killbill.billing.catalog.api.Duration;
import org.killbill.billing.catalog.api.PhaseType;
import org.killbill.billing.catalog.api.PlanPhasePriceOverride;
import org.killbill.billing.catalog.api.PlanPhaseSpecifier;
-import org.killbill.billing.catalog.api.ProductCategory;
import org.killbill.billing.catalog.api.TimeUnit;
+import org.killbill.billing.dao.MockNonEntityDao;
+import org.killbill.billing.entitlement.api.EntitlementSpecifier;
import org.killbill.billing.entitlement.api.SubscriptionEventType;
import org.killbill.billing.invoice.api.DryRunArguments;
import org.killbill.billing.invoice.api.DryRunType;
import org.killbill.billing.subscription.api.SubscriptionBase;
import org.killbill.billing.subscription.api.SubscriptionBaseInternalApi;
+import org.killbill.billing.subscription.api.SubscriptionBaseWithAddOns;
+import org.killbill.billing.subscription.api.SubscriptionBaseWithAddOnsSpecifier;
import org.killbill.billing.subscription.engine.dao.SubscriptionDao;
import org.killbill.billing.subscription.events.SubscriptionBaseEvent;
import org.killbill.billing.subscription.events.phase.PhaseEvent;
import org.killbill.billing.subscription.events.user.ApiEvent;
import org.killbill.billing.subscription.events.user.ApiEventType;
-import org.killbill.billing.util.callcontext.CallContext;
+import org.killbill.billing.util.callcontext.InternalCallContextFactory;
import org.killbill.clock.Clock;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import com.google.common.collect.ImmutableList;
+
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertNotNull;
@@ -66,49 +71,66 @@ public class TestSubscriptionHelper {
private final SubscriptionBaseInternalApi subscriptionApi;
private final Clock clock;
+ private final MockNonEntityDao mockNonEntityDao;
private final InternalCallContext internalCallContext;
private final TestApiListener testListener;
private final SubscriptionDao dao;
+ private final InternalCallContextFactory internalCallContextFactory;
@Inject
- public TestSubscriptionHelper(final SubscriptionBaseInternalApi subscriptionApi, final Clock clock, final InternalCallContext internallCallContext, final CallContext callContext, final TestApiListener testListener, final SubscriptionDao dao) {
+ public TestSubscriptionHelper(final SubscriptionBaseInternalApi subscriptionApi,
+ final Clock clock,
+ final MockNonEntityDao mockNonEntityDao,
+ final InternalCallContext internalCallContext,
+ final TestApiListener testListener,
+ final SubscriptionDao dao,
+ final InternalCallContextFactory internalCallContextFactory) {
this.subscriptionApi = subscriptionApi;
this.clock = clock;
- this.internalCallContext = internallCallContext;
+ this.mockNonEntityDao = mockNonEntityDao;
+ this.internalCallContext = internalCallContext;
this.testListener = testListener;
this.dao = dao;
+ this.internalCallContextFactory = internalCallContextFactory;
}
public DryRunArguments createDryRunArguments(final UUID subscriptionId, final UUID bundleId, final PlanPhaseSpecifier spec, final LocalDate requestedDate, final SubscriptionEventType type, final BillingActionPolicy billingActionPolicy) {
- return new DryRunArguments() {
+ return new DryRunArguments() {
@Override
public DryRunType getDryRunType() {
return DryRunType.SUBSCRIPTION_ACTION;
}
+
@Override
public PlanPhaseSpecifier getPlanPhaseSpecifier() {
return spec;
}
+
@Override
public SubscriptionEventType getAction() {
return type;
}
+
@Override
public UUID getSubscriptionId() {
return subscriptionId;
}
+
@Override
public LocalDate getEffectiveDate() {
return requestedDate;
}
+
@Override
public UUID getBundleId() {
return bundleId;
}
+
@Override
public BillingActionPolicy getBillingActionPolicy() {
return billingActionPolicy;
}
+
@Override
public List<PlanPhasePriceOverride> getPlanPhasePriceOverrides() {
return null;
@@ -118,32 +140,89 @@ public class TestSubscriptionHelper {
public DefaultSubscriptionBase createSubscription(final SubscriptionBaseBundle bundle, final String productName, final BillingPeriod term, final String planSet, final DateTime requestedDate)
throws SubscriptionBaseApiException {
- return createSubscriptionWithBundle(bundle, null, productName, term, planSet, requestedDate);
+ return createSubscription(bundle, productName, term, planSet, null, requestedDate);
+ }
+
+ public DefaultSubscriptionBase createSubscription(final SubscriptionBaseBundle bundle, final String productName, final BillingPeriod term, final String planSet, final PhaseType phaseType, final DateTime requestedDate)
+ throws SubscriptionBaseApiException {
+ return createSubscription(bundle, null, productName, term, planSet, phaseType, requestedDate);
}
public DefaultSubscriptionBase createSubscription(final SubscriptionBaseBundle bundle, final SubscriptionBase baseSubscription, final String aoProduct, final BillingPeriod aoTerm, final String aoPriceList) throws SubscriptionBaseApiException {
- return createSubscriptionWithBundle(bundle, baseSubscription, aoProduct, aoTerm, aoPriceList, null);
+ return createSubscription(bundle, baseSubscription, aoProduct, aoTerm, aoPriceList, null, null);
}
public DefaultSubscriptionBase createSubscription(final SubscriptionBaseBundle bundle, final String productName, final BillingPeriod term, final String planSet)
throws SubscriptionBaseApiException {
- return createSubscriptionWithBundle(bundle, null, productName, term, planSet, null);
+ return createSubscription(bundle, null, productName, term, planSet, null, null);
+ }
+
+ public DefaultSubscriptionBase createSubscription(final SubscriptionBaseBundle bundle, final SubscriptionBase baseSubscription, final String productName, final BillingPeriod term, final String planSet, final DateTime requestedDate) throws SubscriptionBaseApiException {
+ return createSubscription(bundle, baseSubscription, productName, term, planSet, null, requestedDate);
+ }
+
+ public DefaultSubscriptionBase createSubscription(final boolean noEvents, final SubscriptionBaseBundle bundle, final String productName, final BillingPeriod term, final String planSet) throws SubscriptionBaseApiException {
+ return createSubscription(noEvents, bundle, null, productName, term, planSet, null, null);
}
- public DefaultSubscriptionBase createSubscriptionWithBundle(final SubscriptionBaseBundle bundle, final SubscriptionBase baseSubscription, final String productName, final BillingPeriod term, final String planSet, final DateTime requestedDate)
+ public DefaultSubscriptionBase createSubscription(final SubscriptionBaseBundle bundle, final SubscriptionBase baseSubscription, final String productName, final BillingPeriod term, final String planSet, final PhaseType phaseType, final DateTime requestedDate)
throws SubscriptionBaseApiException {
+ return createSubscription(false, bundle, baseSubscription, productName, term, planSet, phaseType, requestedDate);
+ }
+
+ public DefaultSubscriptionBase createSubscription(final boolean noEvents, @Nullable final SubscriptionBaseBundle bundle, final SubscriptionBase baseSubscription, final String productName, final BillingPeriod term, final String planSet, final PhaseType phaseType, final DateTime requestedDate)
+ throws SubscriptionBaseApiException {
+ // Make sure the right account information is used
+ final InternalCallContext internalCallContext = bundle == null ? this.internalCallContext : internalCallContextFactory.createInternalCallContext(bundle.getAccountId(),
+ ObjectType.ACCOUNT,
+ this.internalCallContext.getUpdatedBy(),
+ this.internalCallContext.getCallOrigin(),
+ this.internalCallContext.getContextUserType(),
+ this.internalCallContext.getUserToken(),
+ this.internalCallContext.getTenantRecordId());
+
+ boolean bundleExists = false;
+ if (bundle != null) {
+ try {
+ bundleExists = (subscriptionApi.getBundleFromId(bundle.getId(), internalCallContext) != null);
+ } catch (final SubscriptionBaseApiException ignored) {
+ }
+ }
- if (requestedDate == null || requestedDate.compareTo(clock.getUTCNow()) <= 0) {
+ if (!noEvents && (requestedDate == null || requestedDate.compareTo(clock.getUTCNow()) <= 0)) {
testListener.pushExpectedEvent(NextEvent.CREATE);
}
- final DefaultSubscriptionBase subscription = (DefaultSubscriptionBase) subscriptionApi.createSubscription(bundle,
- baseSubscription,
- new PlanPhaseSpecifier(productName, term, planSet, null), null,
- requestedDate == null ? clock.getUTCNow() : requestedDate, false, internalCallContext);
+
+ final ImmutableList<EntitlementSpecifier> entitlementSpecifiers = ImmutableList.<EntitlementSpecifier>of(new EntitlementSpecifier() {
+ @Override
+ public PlanPhaseSpecifier getPlanPhaseSpecifier() {
+ return new PlanPhaseSpecifier(productName, term, planSet, phaseType);
+ }
+
+ @Override
+ public List<PlanPhasePriceOverride> getOverrides() {
+ return null;
+ }
+ });
+ final SubscriptionBaseWithAddOnsSpecifier subscriptionBaseWithAddOnsSpecifier = new SubscriptionBaseWithAddOnsSpecifier(bundle == null ||!bundleExists ? null : bundle.getId(),
+ bundle == null ? null : bundle.getExternalKey(),
+ entitlementSpecifiers,
+ requestedDate,
+ false);
+ final SubscriptionBaseWithAddOns subscriptionBaseWithAddOns = subscriptionApi.createBaseSubscriptionsWithAddOns(ImmutableList.<SubscriptionBaseWithAddOnsSpecifier>of(subscriptionBaseWithAddOnsSpecifier),
+ false,
+ internalCallContext).get(0);
+ final DefaultSubscriptionBase subscription = (DefaultSubscriptionBase) subscriptionBaseWithAddOns.getSubscriptionBaseList().get(0);
assertNotNull(subscription);
testListener.assertListenerStatus();
+ mockNonEntityDao.addTenantRecordIdMapping(subscription.getId(), internalCallContext);
+ mockNonEntityDao.addAccountRecordIdMapping(subscription.getId(), internalCallContext);
+
+ mockNonEntityDao.addTenantRecordIdMapping(subscription.getBundleId(), internalCallContext);
+ mockNonEntityDao.addAccountRecordIdMapping(subscription.getBundleId(), internalCallContext);
+
return subscription;
}
@@ -174,8 +253,8 @@ public class TestSubscriptionHelper {
}
public void assertDateWithin(final DateTime in, final DateTime lower, final DateTime upper) {
- assertTrue(in.isEqual(lower) || in.isAfter(lower));
- assertTrue(in.isEqual(upper) || in.isBefore(upper));
+ assertTrue(in.isEqual(lower) || in.isAfter(lower), "in=" + in + ", lower=" + lower);
+ assertTrue(in.isEqual(upper) || in.isBefore(upper), "in=" + in + ", upper=" + upper);
}
public Duration getDurationMonth(final int months) {
diff --git a/subscription/src/test/java/org/killbill/billing/subscription/api/user/TestUserApiCancel.java b/subscription/src/test/java/org/killbill/billing/subscription/api/user/TestUserApiCancel.java
index 86c6d90..63114db 100644
--- a/subscription/src/test/java/org/killbill/billing/subscription/api/user/TestUserApiCancel.java
+++ b/subscription/src/test/java/org/killbill/billing/subscription/api/user/TestUserApiCancel.java
@@ -206,9 +206,8 @@ public class TestUserApiCancel extends SubscriptionTestSuiteWithEmbeddedDB {
// Similar test to testCancelSubscriptionEOTWithChargeThroughDate except we uncancel and check things
// are as they used to be and we can move forward without hitting cancellation
- // Flaky, see https://github.com/killbill/killbill/issues/860
- @Test(groups = "slow", retryAnalyzer = FlakyRetryAnalyzer.class)
- public void testUncancel() throws SubscriptionBillingApiException, SubscriptionBaseApiException {
+ @Test(groups = "slow")
+ public void testUncancel() throws SubscriptionBaseApiException {
final String prod = "Shotgun";
final BillingPeriod term = BillingPeriod.MONTHLY;
final String planSet = PriceListSet.DEFAULT_PRICELIST_NAME;
@@ -224,8 +223,7 @@ public class TestUserApiCancel extends SubscriptionTestSuiteWithEmbeddedDB {
// MOVE TO NEXT PHASE
testListener.pushExpectedEvent(NextEvent.PHASE);
- Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(31));
- clock.addDeltaFromReality(it.toDurationMillis());
+ clock.addMonths(1);
assertListenerStatus();
PlanPhase currentPhase = subscription.getCurrentPhase();
assertEquals(currentPhase.getPhaseType(), PhaseType.EVERGREEN);
@@ -238,21 +236,21 @@ public class TestUserApiCancel extends SubscriptionTestSuiteWithEmbeddedDB {
// CANCEL EOT
subscription.cancel(callContext);
+ assertListenerStatus();
+ // UNCANCEL
+ testListener.pushExpectedEvent(NextEvent.UNCANCEL);
subscription.uncancel(callContext);
+ assertListenerStatus();
// MOVE TO EOT + RECHECK
- testListener.pushExpectedEvent(NextEvent.UNCANCEL);
- it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusMonths(1));
- clock.addDeltaFromReality(it.toDurationMillis());
+ clock.addMonths(1);
assertListenerStatus();
final Plan currentPlan = subscription.getCurrentPlan();
assertEquals(currentPlan.getProduct().getName(), prod);
currentPhase = subscription.getCurrentPhase();
assertEquals(currentPhase.getPhaseType(), PhaseType.EVERGREEN);
-
- assertListenerStatus();
}
@Test(groups = "slow", expectedExceptions = SubscriptionBaseApiException.class)
@@ -402,12 +400,9 @@ public class TestUserApiCancel extends SubscriptionTestSuiteWithEmbeddedDB {
final BillingPeriod term = BillingPeriod.MONTHLY;
final String planSetName = PriceListSet.DEFAULT_PRICELIST_NAME;
-
final DateTime futureCreationDate = init.plusDays(10);
- DefaultSubscriptionBase subscription = (DefaultSubscriptionBase) subscriptionInternalApi.createSubscription(bundle,
- null,
- testUtil.getProductSpecifier(productName, planSetName, term, null), null, futureCreationDate, false, internalCallContext);
+ DefaultSubscriptionBase subscription = testUtil.createSubscription(bundle, productName, term, planSetName, futureCreationDate);
assertListenerStatus();
assertNotNull(subscription);
assertEquals(subscription.getState(), EntitlementState.PENDING);
diff --git a/subscription/src/test/java/org/killbill/billing/subscription/api/user/TestUserApiChangePlan.java b/subscription/src/test/java/org/killbill/billing/subscription/api/user/TestUserApiChangePlan.java
index b0202d2..9b83b81 100644
--- a/subscription/src/test/java/org/killbill/billing/subscription/api/user/TestUserApiChangePlan.java
+++ b/subscription/src/test/java/org/killbill/billing/subscription/api/user/TestUserApiChangePlan.java
@@ -494,7 +494,7 @@ public class TestUserApiChangePlan extends SubscriptionTestSuiteWithEmbeddedDB {
// First try with default api (no date -> IMM) => Call should fail because subscription is PENDING
final DryRunArguments dryRunArguments1 = testUtil.createDryRunArguments(subscription.getId(), subscription.getBundleId(), spec, null, SubscriptionEventType.CHANGE, null);
- final List<SubscriptionBase> result1 = subscriptionInternalApi.getSubscriptionsForBundle(bundle.getId(), dryRunArguments1, internalCallContext);
+ final List<SubscriptionBase> result1 = subscriptionInternalApi.getSubscriptionsForBundle(subscription.getBundleId(), dryRunArguments1, internalCallContext);
// Check we are seeing the right PENDING transition (pistol-monthly), not the START but the CHANGE on the same date
assertEquals(((DefaultSubscriptionBase) result1.get(0)).getCurrentOrPendingPlan().getName(), "pistol-monthly");
@@ -503,7 +503,7 @@ public class TestUserApiChangePlan extends SubscriptionTestSuiteWithEmbeddedDB {
// Second try with date prior to startDate => Call should fail because subscription is PENDING
try {
final DryRunArguments dryRunArguments2 = testUtil.createDryRunArguments(subscription.getId(), subscription.getBundleId(), spec, new LocalDate(startDate.minusDays(1)), SubscriptionEventType.CHANGE, null);
- subscriptionInternalApi.getSubscriptionsForBundle(bundle.getId(), dryRunArguments2, internalCallContext);
+ subscriptionInternalApi.getSubscriptionsForBundle(subscription.getBundleId(), dryRunArguments2, internalCallContext);
fail("Change plan should have failed : subscription PENDING");
} catch (final SubscriptionBaseApiException e) {
assertEquals(e.getCode(), ErrorCode.SUB_CHANGE_NON_ACTIVE.getCode());
@@ -517,7 +517,7 @@ public class TestUserApiChangePlan extends SubscriptionTestSuiteWithEmbeddedDB {
// Third try with date equals to startDate Call should succeed, but no event because action in future
final DryRunArguments dryRunArguments3 = testUtil.createDryRunArguments(subscription.getId(), subscription.getBundleId(), spec, internalCallContext.toLocalDate(startDate), SubscriptionEventType.CHANGE, null);
- final List<SubscriptionBase> result2 = subscriptionInternalApi.getSubscriptionsForBundle(bundle.getId(), dryRunArguments3, internalCallContext);
+ final List<SubscriptionBase> result2 = subscriptionInternalApi.getSubscriptionsForBundle(subscription.getBundleId(), dryRunArguments3, internalCallContext);
// Check we are seeing the right PENDING transition (pistol-monthly), not the START but the CHANGE on the same date
assertEquals(((DefaultSubscriptionBase) result2.get(0)).getCurrentOrPendingPlan().getName(), "pistol-monthly");
diff --git a/subscription/src/test/java/org/killbill/billing/subscription/api/user/TestUserApiCreate.java b/subscription/src/test/java/org/killbill/billing/subscription/api/user/TestUserApiCreate.java
index 027b801..1cdba9a 100644
--- a/subscription/src/test/java/org/killbill/billing/subscription/api/user/TestUserApiCreate.java
+++ b/subscription/src/test/java/org/killbill/billing/subscription/api/user/TestUserApiCreate.java
@@ -41,6 +41,7 @@ import org.testng.Assert;
import org.testng.annotations.Test;
import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotEquals;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertTrue;
@@ -61,10 +62,8 @@ public class TestUserApiCreate extends SubscriptionTestSuiteWithEmbeddedDB {
final BillingPeriod term = BillingPeriod.MONTHLY;
final String planSetName = PriceListSet.DEFAULT_PRICELIST_NAME;
- testListener.pushExpectedEvents(NextEvent.CREATE, NextEvent.PHASE);
- final DefaultSubscriptionBase subscription = (DefaultSubscriptionBase) subscriptionInternalApi.createSubscription(bundle,
- null,
- testUtil.getProductSpecifier(productName, planSetName, term, null), null, requestedDate, false, internalCallContext);
+ testListener.pushExpectedEvents(NextEvent.PHASE);
+ final DefaultSubscriptionBase subscription = testUtil.createSubscription(bundle, productName, term, planSetName, requestedDate);
assertListenerStatus();
assertNotNull(subscription);
@@ -90,21 +89,13 @@ public class TestUserApiCreate extends SubscriptionTestSuiteWithEmbeddedDB {
final SubscriptionBaseBundle newBundle = subscriptionInternalApi.createBundleForAccount(bundle.getAccountId(), DefaultSubscriptionTestInitializer.DEFAULT_BUNDLE_KEY, true, internalCallContext);
assertNotNull(newBundle);
- assertEquals(newBundle.getOriginalCreatedDate().compareTo(bundle.getCreatedDate()), 0);
-
-
- testListener.pushExpectedEvents(NextEvent.CREATE, NextEvent.PHASE);
- final DefaultSubscriptionBase newSubscription = (DefaultSubscriptionBase) subscriptionInternalApi.createSubscription(newBundle,
- null,
- testUtil.getProductSpecifier(productName, planSetName, term, null), null, requestedDate, false, internalCallContext);
+ assertNotEquals(newBundle.getId(), subscription.getBundleId());
+ assertEquals(newBundle.getExternalKey(), DefaultSubscriptionTestInitializer.DEFAULT_BUNDLE_KEY);
+ assertEquals(newBundle.getOriginalCreatedDate().compareTo(bundle.getCreatedDate()), 0, String.format("OriginalCreatedDate=%s != CreatedDate=%s", newBundle.getOriginalCreatedDate(), bundle.getCreatedDate()));
subscriptionInternalApi.updateExternalKey(newBundle.getId(), "myNewSuperKey", internalCallContext);
-
final SubscriptionBaseBundle bundleWithNewKey = subscriptionInternalApi.getBundleFromId(newBundle.getId(), internalCallContext);
assertEquals(bundleWithNewKey.getExternalKey(), "myNewSuperKey");
-
- assertListenerStatus();
- assertNotNull(newSubscription);
}
@Test(groups = "slow")
@@ -117,11 +108,7 @@ public class TestUserApiCreate extends SubscriptionTestSuiteWithEmbeddedDB {
final String planSetName = PriceListSet.DEFAULT_PRICELIST_NAME;
testListener.pushExpectedEvent(NextEvent.PHASE);
- testListener.pushExpectedEvent(NextEvent.CREATE);
-
- final DefaultSubscriptionBase subscription = (DefaultSubscriptionBase) subscriptionInternalApi.createSubscription(bundle,
- null,
- testUtil.getProductSpecifier(productName, planSetName, term, null), null, requestedDate, false, internalCallContext);
+ final DefaultSubscriptionBase subscription = testUtil.createSubscription(bundle, productName, term, planSetName, requestedDate);
assertNotNull(subscription);
//
@@ -134,7 +121,7 @@ public class TestUserApiCreate extends SubscriptionTestSuiteWithEmbeddedDB {
final SubscriptionBaseEvent trialEvent = events.get(0);
final SubscriptionBaseEvent phaseEvent = events.get(1);
- assertEquals(subscription.getBundleId(), bundle.getId());
+ assertEquals(subscription.getBundleExternalKey(), bundle.getExternalKey());
assertEquals(subscription.getStartDate(), requestedDate);
assertListenerStatus();
@@ -156,14 +143,10 @@ public class TestUserApiCreate extends SubscriptionTestSuiteWithEmbeddedDB {
final BillingPeriod term = BillingPeriod.MONTHLY;
final String planSetName = PriceListSet.DEFAULT_PRICELIST_NAME;
- testListener.pushExpectedEvent(NextEvent.CREATE);
-
- final DefaultSubscriptionBase subscription = (DefaultSubscriptionBase) subscriptionInternalApi.createSubscription(bundle,
- null,
- testUtil.getProductSpecifier(productName, planSetName, term, PhaseType.EVERGREEN), null, clock.getUTCNow(), false, internalCallContext);
+ final DefaultSubscriptionBase subscription = testUtil.createSubscription(bundle, productName, term, planSetName, PhaseType.EVERGREEN, clock.getUTCNow());
assertNotNull(subscription);
- assertEquals(subscription.getBundleId(), bundle.getId());
+ assertEquals(subscription.getBundleExternalKey(), bundle.getExternalKey());
testUtil.assertDateWithin(subscription.getStartDate(), init, clock.getUTCNow());
testUtil.assertDateWithin(subscription.getBundleStartDate(), init, clock.getUTCNow());
@@ -188,15 +171,10 @@ public class TestUserApiCreate extends SubscriptionTestSuiteWithEmbeddedDB {
final BillingPeriod term = BillingPeriod.MONTHLY;
final String planSetName = PriceListSet.DEFAULT_PRICELIST_NAME;
- testListener.pushExpectedEvent(NextEvent.CREATE);
-
- final DefaultSubscriptionBase subscription = (DefaultSubscriptionBase) subscriptionInternalApi.createSubscription(bundle,
- null,
- testUtil.getProductSpecifier(productName, planSetName, term, null),
- null, clock.getUTCNow(), false, internalCallContext);
+ final DefaultSubscriptionBase subscription = testUtil.createSubscription(bundle, productName, term, planSetName, clock.getUTCNow());
assertNotNull(subscription);
- assertEquals(subscription.getBundleId(), bundle.getId());
+ assertEquals(subscription.getBundleExternalKey(), bundle.getExternalKey());
testUtil.assertDateWithin(subscription.getStartDate(), init, clock.getUTCNow());
testUtil.assertDateWithin(subscription.getBundleStartDate(), init, clock.getUTCNow());
@@ -236,13 +214,8 @@ public class TestUserApiCreate extends SubscriptionTestSuiteWithEmbeddedDB {
final BillingPeriod term = BillingPeriod.ANNUAL;
final String planSetName = "gunclubDiscount";
- testListener.pushExpectedEvent(NextEvent.CREATE);
-
// CREATE SUBSCRIPTION
- DefaultSubscriptionBase subscription = (DefaultSubscriptionBase) subscriptionInternalApi.createSubscription(bundle,
- null,
- testUtil.getProductSpecifier(productName, planSetName, term, null),
- null, clock.getUTCNow(), false, internalCallContext);
+ DefaultSubscriptionBase subscription = testUtil.createSubscription(bundle, productName, term, planSetName, clock.getUTCNow());
assertNotNull(subscription);
PlanPhase currentPhase = subscription.getCurrentPhase();
@@ -279,12 +252,7 @@ public class TestUserApiCreate extends SubscriptionTestSuiteWithEmbeddedDB {
final BillingPeriod term = BillingPeriod.ANNUAL;
final String planSetName = PriceListSet.DEFAULT_PRICELIST_NAME;
- testListener.pushExpectedEvent(NextEvent.CREATE);
-
- final DefaultSubscriptionBase subscription = (DefaultSubscriptionBase) subscriptionInternalApi.createSubscription(bundle,
- null,
- testUtil.getProductSpecifier(productName, planSetName, term, null),
- null, clock.getUTCNow(), false, internalCallContext);
+ final DefaultSubscriptionBase subscription = testUtil.createSubscription(bundle, productName, term, planSetName, clock.getUTCNow());
assertNotNull(subscription);
assertListenerStatus();
@@ -301,9 +269,7 @@ public class TestUserApiCreate extends SubscriptionTestSuiteWithEmbeddedDB {
final DateTime futureCreationDate = init.plusDays(10);
- DefaultSubscriptionBase subscription = (DefaultSubscriptionBase) subscriptionInternalApi.createSubscription(bundle,
- null,
- testUtil.getProductSpecifier(productName, planSetName, term, null), null, futureCreationDate, false, internalCallContext);
+ DefaultSubscriptionBase subscription = testUtil.createSubscription(bundle, productName, term, planSetName, futureCreationDate);
assertListenerStatus();
assertNotNull(subscription);
assertEquals(subscription.getState(), EntitlementState.PENDING);
diff --git a/subscription/src/test/java/org/killbill/billing/subscription/api/user/TestUserApiError.java b/subscription/src/test/java/org/killbill/billing/subscription/api/user/TestUserApiError.java
index 47b6164..3393722 100644
--- a/subscription/src/test/java/org/killbill/billing/subscription/api/user/TestUserApiError.java
+++ b/subscription/src/test/java/org/killbill/billing/subscription/api/user/TestUserApiError.java
@@ -58,8 +58,8 @@ public class TestUserApiError extends SubscriptionTestSuiteNoDB {
}
@Test(groups = "fast")
- public void testCreateSubscriptionNoBundle() {
- tCreateSubscriptionInternal(null, "Shotgun", BillingPeriod.ANNUAL, PriceListSet.DEFAULT_PRICELIST_NAME, ErrorCode.SUB_CREATE_NO_BUNDLE);
+ public void testCreateSubscriptionNoBundle() throws SubscriptionBaseApiException {
+ testUtil.createSubscription(null, "Shotgun", BillingPeriod.ANNUAL, PriceListSet.DEFAULT_PRICELIST_NAME);
}
@Test(groups = "fast")
@@ -68,59 +68,35 @@ public class TestUserApiError extends SubscriptionTestSuiteNoDB {
}
@Test(groups = "fast")
- public void testCreateSubscriptionBPExists() throws SubscriptionBaseApiException {
- testUtil.createSubscription(bundle, "Shotgun", BillingPeriod.ANNUAL, PriceListSet.DEFAULT_PRICELIST_NAME);
- tCreateSubscriptionInternal(bundle, "Shotgun", BillingPeriod.ANNUAL, PriceListSet.DEFAULT_PRICELIST_NAME, ErrorCode.SUB_CREATE_BP_EXISTS);
- }
-
- @Test(groups = "fast")
public void testCreateSubscriptionAddOnNotAvailable() throws SubscriptionBaseApiException {
- final SubscriptionBaseBundle aoBundle = subscriptionInternalApi.createBundleForAccount(bundle.getAccountId(), "myAOBundle", true, internalCallContext);
- mockNonEntityDao.addTenantRecordIdMapping(aoBundle.getId(), internalCallContext);
- mockNonEntityDao.addAccountRecordIdMapping(aoBundle.getId(), internalCallContext);
-
- testUtil.createSubscriptionWithBundle(aoBundle, null, "Pistol", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null);
- tCreateSubscriptionInternal(aoBundle, "Telescopic-Scope", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, ErrorCode.SUB_CREATE_AO_NOT_AVAILABLE);
+ testUtil.createSubscription(bundle, "Pistol", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME);
+ tCreateSubscriptionInternal(bundle, "Telescopic-Scope", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, ErrorCode.SUB_CREATE_AO_NOT_AVAILABLE);
}
@Test(groups = "fast")
public void testCreateSubscriptionAddOnIncluded() throws SubscriptionBaseApiException {
- final SubscriptionBaseBundle aoBundle = subscriptionInternalApi.createBundleForAccount(bundle.getAccountId(), "myAOBundle", true, internalCallContext);
- mockNonEntityDao.addTenantRecordIdMapping(aoBundle.getId(), internalCallContext);
- mockNonEntityDao.addAccountRecordIdMapping(aoBundle.getId(), internalCallContext);
-
- testUtil.createSubscriptionWithBundle(aoBundle, null, "Assault-Rifle", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null);
- tCreateSubscriptionInternal(aoBundle, "Telescopic-Scope", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, ErrorCode.SUB_CREATE_AO_ALREADY_INCLUDED);
+ testUtil.createSubscription(bundle, "Assault-Rifle", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME);
+ tCreateSubscriptionInternal(bundle, "Telescopic-Scope", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, ErrorCode.SUB_CREATE_AO_ALREADY_INCLUDED);
}
private void tCreateSubscriptionInternal(@Nullable final SubscriptionBaseBundle bundle, @Nullable final String productName,
@Nullable final BillingPeriod term, final String planSet, final ErrorCode expected) {
- SubscriptionBase baseSubscription = null;
- if (bundle != null) {
- try {
- baseSubscription = subscriptionInternalApi.getBaseSubscription(bundle.getId(), internalCallContext);
- } catch (final SubscriptionBaseApiException ignored) {
- }
- }
-
try {
- subscriptionInternalApi.createSubscription(bundle,
- baseSubscription,
- testUtil.getProductSpecifier(productName, planSet, term, null),
- null, clock.getUTCNow(), false, internalCallContext);
+ testUtil.createSubscription(true, bundle, productName, term, planSet);
Assert.fail("Exception expected, error code: " + expected);
} catch (final SubscriptionBaseApiException e) {
assertEquals(e.getCode(), expected.getCode());
}
}
- // Flaky, see https://github.com/killbill/killbill/issues/860
- @Test(groups = "fast", retryAnalyzer = FlakyRetryAnalyzer.class)
+ @Test(groups = "fast")
public void testChangeSubscriptionNonActive() throws SubscriptionBaseApiException {
final SubscriptionBase subscription = testUtil.createSubscription(bundle, "Shotgun", BillingPeriod.ANNUAL, PriceListSet.DEFAULT_PRICELIST_NAME);
testListener.pushExpectedEvent(NextEvent.CANCEL);
subscription.cancelWithDate(clock.getUTCNow(), callContext);
+ assertListenerStatus();
+
try {
subscription.changePlanWithDate(new PlanPhaseSpecifier("Pistol", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME), null, clock.getUTCNow(), callContext);
Assert.fail("Exception expected, error code: " + ErrorCode.SUB_CHANGE_NON_ACTIVE);
diff --git a/subscription/src/test/java/org/killbill/billing/subscription/DefaultSubscriptionTestInitializer.java b/subscription/src/test/java/org/killbill/billing/subscription/DefaultSubscriptionTestInitializer.java
index b0a541b..8da169d 100644
--- a/subscription/src/test/java/org/killbill/billing/subscription/DefaultSubscriptionTestInitializer.java
+++ b/subscription/src/test/java/org/killbill/billing/subscription/DefaultSubscriptionTestInitializer.java
@@ -34,6 +34,7 @@ import org.killbill.billing.lifecycle.api.BusService;
import org.killbill.billing.mock.MockAccountBuilder;
import org.killbill.billing.subscription.api.SubscriptionBaseInternalApi;
import org.killbill.billing.subscription.api.SubscriptionBaseService;
+import org.killbill.billing.subscription.api.user.DefaultSubscriptionBaseBundle;
import org.killbill.billing.subscription.api.user.SubscriptionBaseBundle;
import org.killbill.billing.subscription.engine.core.DefaultSubscriptionBaseService;
import org.killbill.billing.util.UUIDs;
@@ -80,10 +81,9 @@ public class DefaultSubscriptionTestInitializer implements SubscriptionTestIniti
return accountData;
}
- public SubscriptionBaseBundle initBundle(final UUID accountId, final SubscriptionBaseInternalApi subscriptionApi, final InternalCallContext callContext) throws Exception {
- final SubscriptionBaseBundle bundle = subscriptionApi.createBundleForAccount(accountId, DEFAULT_BUNDLE_KEY, true, callContext);
- assertNotNull(bundle);
- return bundle;
+ public SubscriptionBaseBundle initBundle(final UUID accountId, final SubscriptionBaseInternalApi subscriptionApi, final Clock clock, final InternalCallContext callContext) throws Exception {
+ final DateTime utcNow = clock.getUTCNow();
+ return new DefaultSubscriptionBaseBundle(DEFAULT_BUNDLE_KEY, accountId, utcNow, utcNow, utcNow, utcNow);
}
public void startTestFramework(final TestApiListener testListener,
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 d0afd23..19dbef1 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
@@ -70,6 +70,7 @@ import org.killbill.notificationq.api.NotificationQueueService.NoSuchNotificatio
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import com.google.common.base.MoreObjects;
import com.google.inject.Inject;
public class MockSubscriptionDaoMemory extends MockEntityDaoBase<SubscriptionBundleModelDao, SubscriptionBaseBundle, SubscriptionApiException> implements SubscriptionDao {
@@ -175,7 +176,13 @@ public class MockSubscriptionDaoMemory extends MockEntityDaoBase<SubscriptionBun
@Override
public SubscriptionBaseBundle createSubscriptionBundle(final DefaultSubscriptionBaseBundle bundle, final Catalog catalog, final boolean renameCancelledBundleIfExist, final InternalCallContext context) {
- bundles.add(bundle);
+ bundles.add(new DefaultSubscriptionBaseBundle(bundle.getId(),
+ MoreObjects.firstNonNull(bundle.getExternalKey(), UUID.randomUUID().toString()),
+ bundle.getAccountId(),
+ bundle.getLastSysUpdateDate(),
+ bundle.getOriginalCreatedDate(),
+ bundle.getCreatedDate(),
+ bundle.getUpdatedDate()));
mockNonEntityDao.addTenantRecordIdMapping(bundle.getId(), context);
return getSubscriptionBundleFromId(bundle.getId(), context);
}
@@ -191,44 +198,11 @@ public class MockSubscriptionDaoMemory extends MockEntityDaoBase<SubscriptionBun
}
@Override
- public UUID getAccountIdFromSubscriptionId(final UUID subscriptionId, final InternalTenantContext context) {
- throw new UnsupportedOperationException();
- }
-
- /*
- @Override
- public List<SubscriptionBase> getSubscriptionsForAccountAndKey(final UUID accountId, final String bundleKey, final InternalTenantContext callcontext) {
-
- for (final SubscriptionBaseBundle cur : bundles) {
- if (cur.getExternalKey().equals(bundleKey) && cur.getAccountId().equals(bundleKey)) {
- return getSubscriptions(cur.getId(), callcontext);
- }
- }
- return Collections.emptyList();
- }
- */
-
- @Override
- public List<SubscriptionBaseEvent> createSubscription(final DefaultSubscriptionBase subscription, final List<SubscriptionBaseEvent> initialEvents,
- final Catalog catalog, final InternalCallContext context) {
- synchronized (events) {
- events.addAll(initialEvents);
- for (final SubscriptionBaseEvent cur : initialEvents) {
- recordFutureNotificationFromTransaction(null, cur.getEffectiveDate(), new SubscriptionNotificationKey(cur.getId()), context);
- }
- }
- final SubscriptionBase updatedSubscription = buildSubscription(subscription, context);
- subscriptions.add(updatedSubscription);
- mockNonEntityDao.addTenantRecordIdMapping(updatedSubscription.getId(), context);
-
- return initialEvents;
- }
-
- @Override
- public void createSubscriptionsWithAddOns(final List<SubscriptionBaseWithAddOns> subscriptions,
- final Map<UUID, List<SubscriptionBaseEvent>> initialEventsMap,
- final Catalog catalog,
- final InternalCallContext context) {
+ public List<SubscriptionBaseEvent> createSubscriptionsWithAddOns(final List<SubscriptionBaseWithAddOns> subscriptions,
+ final Map<UUID, List<SubscriptionBaseEvent>> initialEventsMap,
+ final Catalog catalog,
+ final InternalCallContext context) {
+ final List<SubscriptionBaseEvent> createdEvents = new LinkedList<SubscriptionBaseEvent>();
synchronized (events) {
for (final SubscriptionBaseWithAddOns subscription : subscriptions) {
for (final SubscriptionBase subscriptionBase : subscription.getSubscriptionBaseList()) {
@@ -240,9 +214,13 @@ public class MockSubscriptionDaoMemory extends MockEntityDaoBase<SubscriptionBun
final SubscriptionBase updatedSubscription = buildSubscription((DefaultSubscriptionBase) subscriptionBase, context);
this.subscriptions.add(updatedSubscription);
mockNonEntityDao.addTenantRecordIdMapping(updatedSubscription.getId(), context);
+
+ createdEvents.addAll(initialEvents);
}
}
}
+
+ return createdEvents;
}
@Override
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 2fc6531..253bf4a 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
@@ -1,6 +1,6 @@
/*
- * 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
@@ -28,8 +28,11 @@ import org.killbill.billing.api.TestApiListener.NextEvent;
import org.killbill.billing.catalog.DefaultPriceListSet;
import org.killbill.billing.catalog.api.ProductCategory;
import org.killbill.billing.subscription.SubscriptionTestSuiteWithEmbeddedDB;
+import org.killbill.billing.subscription.api.SubscriptionBase;
+import org.killbill.billing.subscription.api.SubscriptionBaseWithAddOns;
import org.killbill.billing.subscription.api.user.DefaultSubscriptionBase;
import org.killbill.billing.subscription.api.user.DefaultSubscriptionBaseBundle;
+import org.killbill.billing.subscription.api.user.DefaultSubscriptionBaseWithAddOns;
import org.killbill.billing.subscription.api.user.SubscriptionBaseApiException;
import org.killbill.billing.subscription.api.user.SubscriptionBaseBundle;
import org.killbill.billing.subscription.api.user.SubscriptionBuilder;
@@ -46,6 +49,7 @@ import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
import static org.testng.Assert.assertEquals;
@@ -111,7 +115,12 @@ public class TestSubscriptionDao extends SubscriptionTestSuiteWithEmbeddedDB {
final DefaultSubscriptionBase subscription = new DefaultSubscriptionBase(builder);
testListener.pushExpectedEvents(NextEvent.CREATE);
- dao.createSubscription(subscription, ImmutableList.of(creationEvent), catalog, internalCallContext);
+ final SubscriptionBaseWithAddOns subscriptionBaseWithAddOns = new DefaultSubscriptionBaseWithAddOns(bundle,
+ ImmutableList.<SubscriptionBase>of(subscription));
+ dao.createSubscriptionsWithAddOns(ImmutableList.<SubscriptionBaseWithAddOns>of(subscriptionBaseWithAddOns),
+ ImmutableMap.<UUID, List<SubscriptionBaseEvent>>of(subscription.getId(), ImmutableList.<SubscriptionBaseEvent>of(creationEvent)),
+ catalog,
+ internalCallContext);
assertListenerStatus();
// Operation Should now fail
diff --git a/subscription/src/test/java/org/killbill/billing/subscription/SubscriptionTestInitializer.java b/subscription/src/test/java/org/killbill/billing/subscription/SubscriptionTestInitializer.java
index 68a9921..dea2503 100644
--- a/subscription/src/test/java/org/killbill/billing/subscription/SubscriptionTestInitializer.java
+++ b/subscription/src/test/java/org/killbill/billing/subscription/SubscriptionTestInitializer.java
@@ -39,7 +39,7 @@ public interface SubscriptionTestInitializer {
public AccountData initAccountData(Clock clock);
- public SubscriptionBaseBundle initBundle(final UUID accountId, final SubscriptionBaseInternalApi subscriptionApi, final InternalCallContext callContext) throws Exception;
+ public SubscriptionBaseBundle initBundle(final UUID accountId, final SubscriptionBaseInternalApi subscriptionApi, final Clock clock, final InternalCallContext callContext) throws Exception;
public void startTestFramework(final TestApiListener testListener,
final ClockMock clock,
diff --git a/subscription/src/test/java/org/killbill/billing/subscription/SubscriptionTestSuiteNoDB.java b/subscription/src/test/java/org/killbill/billing/subscription/SubscriptionTestSuiteNoDB.java
index 8563da4..5daabf1 100644
--- a/subscription/src/test/java/org/killbill/billing/subscription/SubscriptionTestSuiteNoDB.java
+++ b/subscription/src/test/java/org/killbill/billing/subscription/SubscriptionTestSuiteNoDB.java
@@ -23,7 +23,10 @@ import java.util.UUID;
import javax.inject.Inject;
import org.killbill.billing.GuicyKillbillTestSuiteNoDB;
+import org.killbill.billing.account.api.Account;
import org.killbill.billing.account.api.AccountData;
+import org.killbill.billing.account.api.AccountInternalApi;
+import org.killbill.billing.account.api.AccountUserApi;
import org.killbill.billing.account.api.ImmutableAccountData;
import org.killbill.billing.account.api.ImmutableAccountInternalApi;
import org.killbill.billing.api.TestApiListener;
@@ -31,7 +34,6 @@ import org.killbill.billing.callcontext.InternalTenantContext;
import org.killbill.billing.catalog.api.Catalog;
import org.killbill.billing.catalog.api.CatalogInternalApi;
import org.killbill.billing.catalog.api.CatalogService;
-import org.killbill.billing.catalog.api.CatalogUserApi;
import org.killbill.billing.dao.MockNonEntityDao;
import org.killbill.billing.lifecycle.api.BusService;
import org.killbill.billing.platform.api.KillbillConfigSource;
@@ -60,13 +62,16 @@ import org.testng.annotations.BeforeMethod;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.Stage;
-import org.killbill.billing.util.UUIDs;
public class SubscriptionTestSuiteNoDB extends GuicyKillbillTestSuiteNoDB {
protected static final Logger log = LoggerFactory.getLogger(SubscriptionTestSuiteNoDB.class);
@Inject
+ protected AccountUserApi accountUserApi;
+ @Inject
+ protected AccountInternalApi accountInternalApi;
+ @Inject
protected ImmutableAccountInternalApi immutableAccountInternalApi;
@Inject
protected SubscriptionBaseService subscriptionBaseService;
@@ -131,7 +136,6 @@ public class SubscriptionTestSuiteNoDB extends GuicyKillbillTestSuiteNoDB {
@BeforeMethod(groups = "fast")
public void beforeMethod() throws Exception {
-
// CLEANUP ALL DB TABLES OR IN MEMORY STRUCTURES
((MockSubscriptionDaoMemory) dao).reset();
@@ -139,13 +143,25 @@ public class SubscriptionTestSuiteNoDB extends GuicyKillbillTestSuiteNoDB {
this.catalog = subscriptionTestInitializer.initCatalog(catalogService, internalCallContext);
this.accountData = subscriptionTestInitializer.initAccountData(clock);
- final UUID accountId = UUIDs.randomUUID();
+
+ final Account account = GuicyKillbillTestSuiteNoDB.createMockAccount(accountData,
+ accountUserApi,
+ accountInternalApi,
+ immutableAccountInternalApi,
+ mockNonEntityDao,
+ clock,
+ internalCallContextFactory,
+ callContext,
+ internalCallContext);
+ final UUID accountId = account.getId();
+ mockNonEntityDao.addAccountRecordIdMapping(accountId, internalCallContext);
mockNonEntityDao.addTenantRecordIdMapping(accountId, internalCallContext);
+ mockNonEntityDao.addAccountIdMapping(internalCallContext.getAccountRecordId(), accountId);
final ImmutableAccountData immutableAccountData = Mockito.mock(ImmutableAccountData.class);
Mockito.when(immutableAccountInternalApi.getImmutableAccountDataByRecordId(Mockito.<Long>eq(internalCallContext.getAccountRecordId()), Mockito.<InternalTenantContext>any())).thenReturn(immutableAccountData);
- this.bundle = subscriptionTestInitializer.initBundle(accountId, subscriptionInternalApi, internalCallContext);
+ this.bundle = subscriptionTestInitializer.initBundle(accountId, subscriptionInternalApi, clock, internalCallContext);
mockNonEntityDao.addTenantRecordIdMapping(bundle.getId(), internalCallContext);
mockNonEntityDao.addAccountRecordIdMapping(bundle.getId(), internalCallContext);
}
diff --git a/subscription/src/test/java/org/killbill/billing/subscription/SubscriptionTestSuiteWithEmbeddedDB.java b/subscription/src/test/java/org/killbill/billing/subscription/SubscriptionTestSuiteWithEmbeddedDB.java
index 2b5da99..fb54d56 100644
--- a/subscription/src/test/java/org/killbill/billing/subscription/SubscriptionTestSuiteWithEmbeddedDB.java
+++ b/subscription/src/test/java/org/killbill/billing/subscription/SubscriptionTestSuiteWithEmbeddedDB.java
@@ -1,7 +1,7 @@
/*
* Copyright 2010-2013 Ning, Inc.
- * Copyright 2014-2015 Groupon, Inc
- * Copyright 2014-2015 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
@@ -120,7 +120,8 @@ public class SubscriptionTestSuiteWithEmbeddedDB extends GuicyKillbillTestSuiteW
this.catalog = subscriptionTestInitializer.initCatalog(catalogService, internalCallContext);
this.accountData = subscriptionTestInitializer.initAccountData(clock);
final Account account = createAccount(accountData);
- this.bundle = subscriptionTestInitializer.initBundle(account.getId(), subscriptionInternalApi, internalCallContext);
+ final SubscriptionBaseBundle model = subscriptionTestInitializer.initBundle(account.getId(), subscriptionInternalApi, clock, internalCallContext);
+ this.bundle = subscriptionInternalApi.createBundleForAccount(model.getAccountId(), model.getExternalKey(), false, internalCallContext);
}
@AfterMethod(groups = "slow")
diff --git a/util/src/main/java/org/killbill/billing/util/cache/AccountIdFromBundleIdCacheLoader.java b/util/src/main/java/org/killbill/billing/util/cache/AccountIdFromBundleIdCacheLoader.java
new file mode 100644
index 0000000..9dd2f3a
--- /dev/null
+++ b/util/src/main/java/org/killbill/billing/util/cache/AccountIdFromBundleIdCacheLoader.java
@@ -0,0 +1,50 @@
+/*
+ * 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
+ * License. You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.killbill.billing.util.cache;
+
+import java.util.UUID;
+
+import javax.inject.Singleton;
+
+import org.killbill.billing.callcontext.InternalTenantContext;
+import org.killbill.billing.util.cache.Cachable.CacheType;
+
+@Singleton
+public class AccountIdFromBundleIdCacheLoader extends BaseCacheLoader<UUID, UUID> {
+
+ @Override
+ public CacheType getCacheType() {
+ return CacheType.ACCOUNT_ID_FROM_BUNDLE_ID;
+ }
+
+ @Override
+ public UUID compute(final UUID key, final CacheLoaderArgument cacheLoaderArgument) {
+ if (cacheLoaderArgument.getArgs() == null ||
+ !(cacheLoaderArgument.getArgs()[0] instanceof LoaderCallback)) {
+ throw new IllegalArgumentException("Missing LoaderCallback from the arguments ");
+ }
+
+ final LoaderCallback callback = (LoaderCallback) cacheLoaderArgument.getArgs()[0];
+ return callback.loadAccountId(key, cacheLoaderArgument.getInternalTenantContext());
+ }
+
+ public interface LoaderCallback {
+
+ UUID loadAccountId(final UUID bundleId, final InternalTenantContext context);
+ }
+}
diff --git a/util/src/main/java/org/killbill/billing/util/cache/BundleIdFromSubscriptionIdCacheLoader.java b/util/src/main/java/org/killbill/billing/util/cache/BundleIdFromSubscriptionIdCacheLoader.java
new file mode 100644
index 0000000..b88d7b7
--- /dev/null
+++ b/util/src/main/java/org/killbill/billing/util/cache/BundleIdFromSubscriptionIdCacheLoader.java
@@ -0,0 +1,50 @@
+/*
+ * 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
+ * License. You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.killbill.billing.util.cache;
+
+import java.util.UUID;
+
+import javax.inject.Singleton;
+
+import org.killbill.billing.callcontext.InternalTenantContext;
+import org.killbill.billing.util.cache.Cachable.CacheType;
+
+@Singleton
+public class BundleIdFromSubscriptionIdCacheLoader extends BaseCacheLoader<UUID, UUID> {
+
+ @Override
+ public CacheType getCacheType() {
+ return CacheType.BUNDLE_ID_FROM_SUBSCRIPTION_ID;
+ }
+
+ @Override
+ public UUID compute(final UUID key, final CacheLoaderArgument cacheLoaderArgument) {
+ if (cacheLoaderArgument.getArgs() == null ||
+ !(cacheLoaderArgument.getArgs()[0] instanceof LoaderCallback)) {
+ throw new IllegalArgumentException("Missing LoaderCallback from the arguments ");
+ }
+
+ final LoaderCallback callback = (LoaderCallback) cacheLoaderArgument.getArgs()[0];
+ return callback.loadBundleId(key, cacheLoaderArgument.getInternalTenantContext());
+ }
+
+ public interface LoaderCallback {
+
+ UUID loadBundleId(final UUID subscriptionId, final InternalTenantContext context);
+ }
+}
diff --git a/util/src/main/java/org/killbill/billing/util/cache/Cachable.java b/util/src/main/java/org/killbill/billing/util/cache/Cachable.java
index 97d5cb6..240ff3c 100644
--- a/util/src/main/java/org/killbill/billing/util/cache/Cachable.java
+++ b/util/src/main/java/org/killbill/billing/util/cache/Cachable.java
@@ -50,6 +50,8 @@ public @interface Cachable {
String OVERRIDDEN_PLAN_CACHE_NAME = "overridden-plan";
String ACCOUNT_IMMUTABLE_CACHE_NAME = "account-immutable";
String ACCOUNT_BCD_CACHE_NAME = "account-bcd";
+ String ACCOUNT_ID_FROM_BUNDLE_ID_CACHE_NAME = "account-id-from-bundle-id";
+ String BUNDLE_ID_FROM_SUBSCRIPTION_ID_CACHE_NAME = "bundle-id-from-subscription-id";
CacheType value();
@@ -99,7 +101,13 @@ public @interface Cachable {
ACCOUNT_IMMUTABLE(ACCOUNT_IMMUTABLE_CACHE_NAME, Long.class, ImmutableAccountData.class, false),
/* Account BCD config cache */
- ACCOUNT_BCD(ACCOUNT_BCD_CACHE_NAME, UUID.class, Integer.class, false);
+ ACCOUNT_BCD(ACCOUNT_BCD_CACHE_NAME, UUID.class, Integer.class, false),
+
+ /* Bundle id to Account id cache */
+ ACCOUNT_ID_FROM_BUNDLE_ID(ACCOUNT_ID_FROM_BUNDLE_ID_CACHE_NAME, UUID.class, UUID.class, false),
+
+ /* Entitlement id to Bundle id cache */
+ BUNDLE_ID_FROM_SUBSCRIPTION_ID(BUNDLE_ID_FROM_SUBSCRIPTION_ID_CACHE_NAME, UUID.class, UUID.class, false);
private final String cacheName;
private final Class keyType;
diff --git a/util/src/main/java/org/killbill/billing/util/glue/CacheModule.java b/util/src/main/java/org/killbill/billing/util/glue/CacheModule.java
index d4ddf25..cb7c571 100644
--- a/util/src/main/java/org/killbill/billing/util/glue/CacheModule.java
+++ b/util/src/main/java/org/killbill/billing/util/glue/CacheModule.java
@@ -1,7 +1,7 @@
/*
* Copyright 2010-2013 Ning, Inc.
- * Copyright 2014-2015 Groupon, Inc
- * Copyright 2014-2015 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
@@ -22,10 +22,12 @@ import javax.cache.CacheManager;
import org.killbill.billing.platform.api.KillbillConfigSource;
import org.killbill.billing.util.cache.AccountBCDCacheLoader;
+import org.killbill.billing.util.cache.AccountIdFromBundleIdCacheLoader;
import org.killbill.billing.util.cache.AccountRecordIdCacheLoader;
import org.killbill.billing.util.cache.AuditLogCacheLoader;
import org.killbill.billing.util.cache.AuditLogViaHistoryCacheLoader;
import org.killbill.billing.util.cache.BaseCacheLoader;
+import org.killbill.billing.util.cache.BundleIdFromSubscriptionIdCacheLoader;
import org.killbill.billing.util.cache.CacheControllerDispatcher;
import org.killbill.billing.util.cache.CacheControllerDispatcherProvider;
import org.killbill.billing.util.cache.ImmutableAccountCacheLoader;
@@ -77,5 +79,7 @@ public class CacheModule extends KillBillModule {
resultSetMapperSetBinder.addBinding().to(TenantCacheLoader.class).asEagerSingleton();
resultSetMapperSetBinder.addBinding().to(OverriddenPlanCacheLoader.class).asEagerSingleton();
resultSetMapperSetBinder.addBinding().to(TenantStateMachineConfigCacheLoader.class).asEagerSingleton();
+ resultSetMapperSetBinder.addBinding().to(AccountIdFromBundleIdCacheLoader.class).asEagerSingleton();
+ resultSetMapperSetBinder.addBinding().to(BundleIdFromSubscriptionIdCacheLoader.class).asEagerSingleton();
}
}
diff --git a/util/src/test/java/org/killbill/billing/dao/MockNonEntityDao.java b/util/src/test/java/org/killbill/billing/dao/MockNonEntityDao.java
index 0a1812e..81159a0 100644
--- a/util/src/test/java/org/killbill/billing/dao/MockNonEntityDao.java
+++ b/util/src/test/java/org/killbill/billing/dao/MockNonEntityDao.java
@@ -1,7 +1,7 @@
/*
* Copyright 2010-2013 Ning, Inc.
- * Copyright 2014-2015 Groupon, Inc
- * Copyright 2014-2015 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
@@ -32,10 +32,13 @@ import org.killbill.billing.util.dao.NonEntitySqlDao;
import org.killbill.billing.util.dao.TableName;
import org.skife.jdbi.v2.Handle;
+import static org.killbill.billing.ObjectType.ACCOUNT;
+
public class MockNonEntityDao implements NonEntityDao {
private final Map<UUID, Long> tenantRecordIdMappings = new HashMap<UUID, Long>();
private final Map<UUID, Long> accountRecordIdMappings = new HashMap<UUID, Long>();
+ private final Map<Long, UUID> accountIdMappings = new HashMap<Long, UUID>();
public void addTenantRecordIdMapping(final UUID objectId, final InternalTenantContext context) {
tenantRecordIdMappings.put(objectId, context.getTenantRecordId());
@@ -45,6 +48,10 @@ public class MockNonEntityDao implements NonEntityDao {
accountRecordIdMappings.put(objectId, context.getAccountRecordId());
}
+ public void addAccountIdMapping(final Long objectRecordId, final UUID objectId) {
+ accountIdMappings.put(objectRecordId, objectId);
+ }
+
@Override
public Long retrieveRecordIdFromObject(final UUID objectId, final ObjectType objectType, @Nullable final CacheController<String, Long> cache) {
return null;
@@ -77,7 +84,11 @@ public class MockNonEntityDao implements NonEntityDao {
@Override
public UUID retrieveIdFromObject(final Long recordId, final ObjectType objectType, @Nullable final CacheController<String, UUID> cache) {
- return null;
+ if (objectType == ACCOUNT) {
+ return accountIdMappings.get(recordId);
+ } else {
+ return null;
+ }
}
@Override
diff --git a/util/src/test/java/org/killbill/billing/GuicyKillbillTestSuiteNoDB.java b/util/src/test/java/org/killbill/billing/GuicyKillbillTestSuiteNoDB.java
index cc2e479..a337c8f 100644
--- a/util/src/test/java/org/killbill/billing/GuicyKillbillTestSuiteNoDB.java
+++ b/util/src/test/java/org/killbill/billing/GuicyKillbillTestSuiteNoDB.java
@@ -1,7 +1,9 @@
/*
* Copyright 2010-2013 Ning, Inc.
+ * Copyright 2014-2018 Groupon, Inc
+ * Copyright 2014-2018 The Billing Project, LLC
*
- * Ning licenses this file to you under the Apache License, version 2.0
+ * 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
* License. You may obtain a copy of the License at:
*
@@ -20,6 +22,7 @@ import java.util.UUID;
import org.killbill.billing.account.api.Account;
import org.killbill.billing.account.api.AccountApiException;
+import org.killbill.billing.account.api.AccountData;
import org.killbill.billing.account.api.AccountInternalApi;
import org.killbill.billing.account.api.AccountUserApi;
import org.killbill.billing.account.api.ImmutableAccountInternalApi;
@@ -34,7 +37,7 @@ import org.mockito.Mockito;
public class GuicyKillbillTestSuiteNoDB extends GuicyKillbillTestSuite {
- public static Account createMockAccount(final Account accountData,
+ public static Account createMockAccount(final AccountData accountData,
final AccountUserApi accountUserApi,
final AccountInternalApi accountInternalApi,
final ImmutableAccountInternalApi immutableAccountInternalApi,