killbill-memoizeit
Changes
.circleci/config.yml 2(+1 -1)
api/src/main/java/org/killbill/billing/subscription/api/SubscriptionBaseWithAddOnsSpecifier.java 8(+4 -4)
entitlement/src/main/java/org/killbill/billing/entitlement/api/DefaultEntitlementApi.java 21(+7 -14)
entitlement/src/main/java/org/killbill/billing/entitlement/api/svcs/DefaultEntitlementApiBase.java 3(+1 -2)
entitlement/src/main/java/org/killbill/billing/entitlement/api/svcs/DefaultEntitlementInternalApi.java 3(+1 -2)
entitlement/src/main/java/org/killbill/billing/entitlement/dao/DefaultBlockingStateDao.java 2(+1 -1)
entitlement/src/main/java/org/killbill/billing/entitlement/logging/EntitlementLoggingHelper.java 51(+23 -28)
invoice/src/main/java/org/killbill/billing/invoice/generator/FixedAndRecurringInvoiceItemGenerator.java 6(+3 -3)
overdue/src/test/java/org/killbill/billing/overdue/calculator/TestBillingStateCalculator.java 3(+2 -1)
payment/src/main/java/org/killbill/billing/payment/core/janitor/IncompletePaymentTransactionTask.java 6(+3 -3)
payment/src/main/java/org/killbill/billing/payment/invoice/InvoicePaymentControlPluginApi.java 12(+6 -6)
payment/src/main/java/org/killbill/billing/payment/provider/ExternalPaymentProviderPlugin.java 12(+6 -6)
subscription/src/main/java/org/killbill/billing/subscription/api/svcs/DefaultSubscriptionInternalApi.java 16(+8 -8)
subscription/src/main/java/org/killbill/billing/subscription/api/transfer/DefaultSubscriptionBaseTransferApi.java 7(+3 -4)
subscription/src/main/java/org/killbill/billing/subscription/api/user/DefaultSubscriptionBaseApiService.java 21(+7 -14)
subscription/src/main/java/org/killbill/billing/subscription/engine/dao/DefaultSubscriptionDao.java 17(+8 -9)
subscription/src/test/java/org/killbill/billing/subscription/api/transfer/TestTransfer.java 6(+3 -3)
subscription/src/test/java/org/killbill/billing/subscription/api/user/TestSubscriptionHelper.java 30(+8 -22)
subscription/src/test/java/org/killbill/billing/subscription/api/user/TestUserApiAddOn.java 14(+7 -7)
subscription/src/test/java/org/killbill/billing/subscription/api/user/TestUserApiCancel.java 27(+13 -14)
subscription/src/test/java/org/killbill/billing/subscription/api/user/TestUserApiChangePlan.java 16(+8 -8)
subscription/src/test/java/org/killbill/billing/subscription/api/user/TestUserApiCreate.java 25(+12 -13)
subscription/src/test/java/org/killbill/billing/subscription/api/user/TestUserApiError.java 1(+0 -1)
subscription/src/test/java/org/killbill/billing/subscription/SubscriptionTestSuiteNoDB.java 3(+1 -2)
subscription/src/test/java/org/killbill/billing/subscription/SubscriptionTestSuiteWithEmbeddedDB.java 2(+0 -2)
util/src/main/java/org/killbill/billing/util/entity/dao/EntitySqlDaoTransactionalJdbiWrapper.java 2(+1 -1)
Details
.circleci/config.yml 2(+1 -1)
diff --git a/.circleci/config.yml b/.circleci/config.yml
index b759366..b81ff31 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -17,7 +17,7 @@ jobs:
name: Setup dependencies
command: |
if [ "${CIRCLE_BRANCH}" != "master" ]; then
- for i in killbill-oss-parent killbill-api killbill-plugin-api killbill-commons killbill-platform; do
+ for i in killbill-oss-parent killbill-api killbill-plugin-api killbill-commons killbill-platform killbill-client-java; do
if [ -n "$(git ls-remote --heads https://github.com/killbill/$i.git ${CIRCLE_BRANCH})" ]; then
echo "*** Setting up $i"
mkdir -p /home/killbill/$i
diff --git a/account/src/main/java/org/killbill/billing/account/dao/DefaultAccountDao.java b/account/src/main/java/org/killbill/billing/account/dao/DefaultAccountDao.java
index d0c412c..dddab19 100644
--- a/account/src/main/java/org/killbill/billing/account/dao/DefaultAccountDao.java
+++ b/account/src/main/java/org/killbill/billing/account/dao/DefaultAccountDao.java
@@ -217,7 +217,7 @@ public class DefaultAccountDao extends EntityDaoBase<AccountModelDao, Account, A
context.getAccountRecordId(),
context.getTenantRecordId(),
context.getUserToken(),
- clock.getUTCNow());
+ context.getCreatedDate());
try {
eventBus.postFromTransaction(changeEvent, entitySqlDaoWrapperFactory.getHandle().getConnection());
} catch (final EventBusException e) {
@@ -254,7 +254,7 @@ public class DefaultAccountDao extends EntityDaoBase<AccountModelDao, Account, A
context.getAccountRecordId(),
context.getTenantRecordId(),
context.getUserToken(),
- clock.getUTCNow());
+ context.getCreatedDate());
try {
eventBus.postFromTransaction(changeEvent, entitySqlDaoWrapperFactory.getHandle().getConnection());
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
index e6a7099..4b95243 100644
--- a/api/src/main/java/org/killbill/billing/subscription/api/SubscriptionBaseWithAddOnsSpecifier.java
+++ b/api/src/main/java/org/killbill/billing/subscription/api/SubscriptionBaseWithAddOnsSpecifier.java
@@ -19,7 +19,7 @@ package org.killbill.billing.subscription.api;
import java.util.UUID;
-import org.joda.time.DateTime;
+import org.joda.time.LocalDate;
import org.killbill.billing.entitlement.api.EntitlementSpecifier;
public class SubscriptionBaseWithAddOnsSpecifier {
@@ -27,13 +27,13 @@ public class SubscriptionBaseWithAddOnsSpecifier {
private final UUID bundleId;
private final String bundleExternalKey;
private final Iterable<EntitlementSpecifier> entitlementSpecifiers;
- private final DateTime billingEffectiveDate;
+ private final LocalDate billingEffectiveDate;
private final boolean isMigrated;
public SubscriptionBaseWithAddOnsSpecifier(final UUID bundleId,
final String bundleExternalKey,
final Iterable<EntitlementSpecifier> entitlementSpecifiers,
- final DateTime billingEffectiveDate,
+ final LocalDate billingEffectiveDate,
final boolean isMigrated) {
this.bundleId = bundleId;
this.bundleExternalKey = bundleExternalKey;
@@ -54,7 +54,7 @@ public class SubscriptionBaseWithAddOnsSpecifier {
return entitlementSpecifiers;
}
- public DateTime getBillingEffectiveDate() {
+ public LocalDate getBillingEffectiveDate() {
return billingEffectiveDate;
}
diff --git a/catalog/src/main/java/org/killbill/billing/catalog/api/user/DefaultCatalogUserApi.java b/catalog/src/main/java/org/killbill/billing/catalog/api/user/DefaultCatalogUserApi.java
index 0373e89..2fee429 100644
--- a/catalog/src/main/java/org/killbill/billing/catalog/api/user/DefaultCatalogUserApi.java
+++ b/catalog/src/main/java/org/killbill/billing/catalog/api/user/DefaultCatalogUserApi.java
@@ -33,7 +33,6 @@ import org.killbill.billing.callcontext.InternalTenantContext;
import org.killbill.billing.catalog.CatalogUpdater;
import org.killbill.billing.catalog.StandaloneCatalog;
import org.killbill.billing.catalog.VersionedCatalog;
-import org.killbill.billing.catalog.api.BillingMode;
import org.killbill.billing.catalog.api.Catalog;
import org.killbill.billing.catalog.api.CatalogApiException;
import org.killbill.billing.catalog.api.CatalogService;
@@ -45,7 +44,6 @@ import org.killbill.billing.catalog.caching.CatalogCache;
import org.killbill.billing.tenant.api.TenantApiException;
import org.killbill.billing.tenant.api.TenantKV.TenantKey;
import org.killbill.billing.tenant.api.TenantUserApi;
-import org.killbill.billing.util.cache.Cachable.CacheType;
import org.killbill.billing.util.callcontext.CallContext;
import org.killbill.billing.util.callcontext.InternalCallContextFactory;
import org.killbill.billing.util.callcontext.TenantContext;
@@ -175,7 +173,7 @@ public class DefaultCatalogUserApi implements CatalogUserApi {
final StandaloneCatalog currentCatalog = getCurrentStandaloneCatalogForTenant(internalTenantContext);
final CatalogUpdater catalogUpdater = (currentCatalog != null) ?
new CatalogUpdater(currentCatalog) :
- new CatalogUpdater(getSafeFirstCatalogEffectiveDate(effectiveDate), null);
+ new CatalogUpdater(getSafeFirstCatalogEffectiveDate(effectiveDate, callContext), null);
catalogCache.clearCatalog(internalTenantContext);
tenantApi.updateTenantKeyValue(TenantKey.CATALOG.toString(), catalogUpdater.getCatalogXML(), callContext);
@@ -192,7 +190,7 @@ public class DefaultCatalogUserApi implements CatalogUserApi {
final StandaloneCatalog currentCatalog = getCurrentStandaloneCatalogForTenant(internalTenantContext);
final CatalogUpdater catalogUpdater = (currentCatalog != null) ?
new CatalogUpdater(currentCatalog) :
- new CatalogUpdater(getSafeFirstCatalogEffectiveDate(effectiveDate), descriptor.getCurrency());
+ new CatalogUpdater(getSafeFirstCatalogEffectiveDate(effectiveDate, callContext), descriptor.getCurrency());
catalogUpdater.addSimplePlanDescriptor(descriptor);
catalogCache.clearCatalog(internalTenantContext);
@@ -209,15 +207,15 @@ public class DefaultCatalogUserApi implements CatalogUserApi {
try {
tenantApi.deleteTenantKey(TenantKey.CATALOG.toString(), callContext);
catalogCache.clearCatalog(internalTenantContext);
- createDefaultEmptyCatalog(clock.getUTCNow(), callContext);
+ createDefaultEmptyCatalog(callContext.getCreatedDate(), callContext);
} catch (final TenantApiException e) {
throw new CatalogApiException(e);
}
}
- private DateTime getSafeFirstCatalogEffectiveDate(@Nullable final DateTime input) {
+ private DateTime getSafeFirstCatalogEffectiveDate(@Nullable final DateTime input, final CallContext callContext) {
// The effectiveDate for the initial version does not matter too much
// Because of #760, we want to make that client passing a approximate date (e.g today.toDateTimeAtStartOfDay()) will find the version
- final DateTime catalogEffectiveDate = clock.getUTCNow().minusDays(1);
+ final DateTime catalogEffectiveDate = callContext.getCreatedDate().minusDays(1);
return (input == null || input.isAfter(catalogEffectiveDate)) ? catalogEffectiveDate : input;
}
diff --git a/entitlement/src/main/java/org/killbill/billing/entitlement/api/DefaultEntitlement.java b/entitlement/src/main/java/org/killbill/billing/entitlement/api/DefaultEntitlement.java
index 79f82d7..c8a4bbd 100644
--- a/entitlement/src/main/java/org/killbill/billing/entitlement/api/DefaultEntitlement.java
+++ b/entitlement/src/main/java/org/killbill/billing/entitlement/api/DefaultEntitlement.java
@@ -347,8 +347,7 @@ public class DefaultEntitlement extends EntityBase implements Entitlement {
final InternalCallContext contextWithValidAccountRecordId = internalCallContextFactory.createInternalCallContext(getAccountId(), callContext);
- final DateTime now = clock.getUTCNow();
- final DateTime billingEffectiveCancelDate = dateHelper.fromLocalDateAndReferenceTimeWithMinimum(billingEffectiveDate, getEventsStream().getSubscriptionBase().getStartDate(), now, contextWithValidAccountRecordId);
+ final DateTime billingEffectiveCancelDate = dateHelper.fromLocalDateAndReferenceTimeWithMinimum(billingEffectiveDate, getEventsStream().getSubscriptionBase().getStartDate(), updatedPluginContext.getCreatedDate(), contextWithValidAccountRecordId);
try {
if (overrideBillingEffectiveDate) {
getSubscriptionBase().cancelWithDate(billingEffectiveCancelDate, callContext);
@@ -359,7 +358,7 @@ public class DefaultEntitlement extends EntityBase implements Entitlement {
throw new EntitlementApiException(e);
}
- final DateTime entitlementEffectiveCancelDate = dateHelper.fromLocalDateAndReferenceTimeWithMinimum(entitlementEffectiveDate, getEventsStream().getEntitlementEffectiveStartDateTime(), now, contextWithValidAccountRecordId);
+ final DateTime entitlementEffectiveCancelDate = dateHelper.fromLocalDateAndReferenceTimeWithMinimum(entitlementEffectiveDate, getEventsStream().getEntitlementEffectiveStartDateTime(), updatedPluginContext.getCreatedDate(), contextWithValidAccountRecordId);
final BlockingState newBlockingState = new DefaultBlockingState(getId(), BlockingStateType.SUBSCRIPTION, DefaultEntitlementApi.ENT_STATE_CANCELLED, EntitlementService.ENTITLEMENT_SERVICE_NAME, true, true, false, entitlementEffectiveCancelDate);
final Collection<NotificationEvent> notificationEvents = new ArrayList<NotificationEvent>();
final Collection<BlockingState> addOnsBlockingStates = computeAddOnBlockingStates(entitlementEffectiveCancelDate, notificationEvents, callContext, contextWithValidAccountRecordId);
@@ -503,8 +502,7 @@ public class DefaultEntitlement extends EntityBase implements Entitlement {
throw new EntitlementApiException(e);
}
- final DateTime now = clock.getUTCNow();
- final DateTime effectiveCancelDate = dateHelper.fromLocalDateAndReferenceTimeWithMinimum(entitlementEffectiveDate, getEventsStream().getEntitlementEffectiveStartDateTime(), now, contextWithValidAccountRecordId);
+ final DateTime effectiveCancelDate = dateHelper.fromLocalDateAndReferenceTimeWithMinimum(entitlementEffectiveDate, getEventsStream().getEntitlementEffectiveStartDateTime(), updatedPluginContext.getCreatedDate(), contextWithValidAccountRecordId);
final BlockingState newBlockingState = new DefaultBlockingState(getId(), BlockingStateType.SUBSCRIPTION, DefaultEntitlementApi.ENT_STATE_CANCELLED, EntitlementService.ENTITLEMENT_SERVICE_NAME, true, true, false, effectiveCancelDate);
final Collection<NotificationEvent> notificationEvents = new ArrayList<NotificationEvent>();
final Collection<BlockingState> addOnsBlockingStates = computeAddOnBlockingStates(effectiveCancelDate, notificationEvents, callContext, contextWithValidAccountRecordId);
@@ -521,19 +519,19 @@ public class DefaultEntitlement extends EntityBase implements Entitlement {
return pluginExecution.executeWithPlugin(cancelEntitlementWithPlugin, pluginContext);
}
- private LocalDate getLocalDateFromEntitlementPolicy(final EntitlementActionPolicy entitlementPolicy, final TenantContext tenantContext) {
- final InternalTenantContext internalTenantContext = internalCallContextFactory.createInternalTenantContext(getAccountId(), tenantContext);
+ private LocalDate getLocalDateFromEntitlementPolicy(final EntitlementActionPolicy entitlementPolicy, final CallContext callContext) {
+ final InternalTenantContext internalTenantContext = internalCallContextFactory.createInternalTenantContext(getAccountId(), callContext);
final LocalDate cancellationDate;
switch (entitlementPolicy) {
case IMMEDIATE:
- cancellationDate = internalTenantContext.toLocalDate(clock.getUTCNow());
+ cancellationDate = internalTenantContext.toLocalDate(callContext.getCreatedDate());
break;
case END_OF_TERM:
if (getSubscriptionBase().getChargedThroughDate() != null) {
cancellationDate = internalTenantContext.toLocalDate(getSubscriptionBase().getChargedThroughDate());
} else {
- cancellationDate = internalTenantContext.toLocalDate(clock.getUTCNow());
+ cancellationDate = internalTenantContext.toLocalDate(callContext.getCreatedDate());
}
break;
default:
@@ -696,9 +694,7 @@ public class DefaultEntitlement extends EntityBase implements Entitlement {
final InternalCallContext context = internalCallContextFactory.createInternalCallContext(getAccountId(), callContext);
-
- final DateTime now = clock.getUTCNow();
- final DateTime effectiveChangeDate = effectiveDate != null ? dateHelper.fromLocalDateAndReferenceTime(effectiveDate, now, context) : null;
+ final DateTime effectiveChangeDate = effectiveDate != null ? dateHelper.fromLocalDateAndReferenceTime(effectiveDate, context.getCreatedDate(), context) : null;
final DateTime resultingEffectiveDate;
try {
@@ -837,8 +833,7 @@ public class DefaultEntitlement extends EntityBase implements Entitlement {
// (e.g. base plan cancellation): future entitlement cancellations for add-ons on disk always reflect
// an explicit cancellation. This trick lets us determine what to do when un-cancelling.
// This mirror the behavior in subscription base (see DefaultSubscriptionBaseApiService).
- final DateTime now = clock.getUTCNow();
- if (effectiveDate.compareTo(now) > 0) {
+ if (effectiveDate.compareTo(internalCallContext.getCreatedDate()) > 0) {
// Note that usually we record the notification from the DAO. We cannot do it here because not all calls
// go through the DAO (e.g. change)
final boolean isBaseEntitlementCancelled = eventsStream.isEntitlementCancelled();
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 a5e8793..475527c 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
@@ -174,7 +174,6 @@ public class DefaultEntitlementApi extends DefaultEntitlementApiBase implements
@Override
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>();
@@ -182,16 +181,14 @@ public class DefaultEntitlementApi extends DefaultEntitlementApiBase implements
for (final BaseEntitlementWithAddOnsSpecifier baseEntitlementWithAddOnsSpecifier : baseEntitlementWithAddOnsSpecifiersAfterPlugins) {
// Entitlement
final DateTime entitlementRequestedDate = dateHelper.fromLocalDateAndReferenceTime(baseEntitlementWithAddOnsSpecifier.getEntitlementEffectiveDate(),
- now,
+ updatedPluginContext.getCreatedDate(),
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.getBillingEffectiveDate(),
baseEntitlementWithAddOnsSpecifier.isMigrated());
subscriptionBaseWithAddOnsSpecifiers.add(subscriptionBaseWithAddOnsSpecifier);
}
@@ -217,7 +214,7 @@ public class DefaultEntitlementApi extends DefaultEntitlementApiBase implements
false,
false,
false,
- dateHelper.fromLocalDateAndReferenceTime(baseEntitlementWithAddOnsSpecifier.getEntitlementEffectiveDate(), now, contextWithValidAccountRecordId));
+ dateHelper.fromLocalDateAndReferenceTime(baseEntitlementWithAddOnsSpecifier.getEntitlementEffectiveDate(), updatedPluginContext.getCreatedDate(), contextWithValidAccountRecordId));
blockingStateMap.put(blockingState, subscriptionsWithAddOns.get(i).getBundle().getId());
createdSubscriptionIds.add(subscriptionBase.getId());
@@ -263,7 +260,6 @@ public class DefaultEntitlementApi extends DefaultEntitlementApiBase implements
@Override
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();
final List<SubscriptionBase> subscriptionsByBundle;
try {
@@ -279,7 +275,7 @@ public class DefaultEntitlementApi extends DefaultEntitlementApiBase implements
final EventsStream eventsStreamForBaseSubscription = isStandalone ? null : eventsStreamBuilder.buildForBaseSubscription(bundleId, callContext);
- final DateTime entitlementRequestedDateRaw = dateHelper.fromLocalDateAndReferenceTime(baseEntitlementWithAddOnsSpecifier.getEntitlementEffectiveDate(), now, context);
+ final DateTime entitlementRequestedDateRaw = dateHelper.fromLocalDateAndReferenceTime(baseEntitlementWithAddOnsSpecifier.getEntitlementEffectiveDate(), updatedPluginContext.getCreatedDate(), context);
DateTime entitlementRequestedDate = entitlementRequestedDateRaw;
if (!isStandalone) {
final DateTime baseEntitlementStartDate = eventsStreamForBaseSubscription.getEntitlementEffectiveStartDateTime();
@@ -289,12 +285,10 @@ public class DefaultEntitlementApi extends DefaultEntitlementApiBase implements
try {
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.getBillingEffectiveDate(),
baseEntitlementWithAddOnsSpecifierAfterPlugins.isMigrated());
final List<SubscriptionBaseWithAddOns> subscriptionsWithAddOns = subscriptionBaseInternalApi.createBaseSubscriptionsWithAddOns(ImmutableList.<SubscriptionBaseWithAddOnsSpecifier>of(subscriptionBaseWithAddOnsSpecifier),
@@ -475,8 +469,7 @@ public class DefaultEntitlementApi extends DefaultEntitlementApiBase implements
final BaseEntitlementWithAddOnsSpecifier baseEntitlementWithAddOnsSpecifier = getFirstBaseEntitlementWithAddOnsSpecifier(updatedPluginContext.getBaseEntitlementWithAddOnsSpecifiers());
- final DateTime now = clock.getUTCNow();
- final DateTime requestedDate = dateHelper.fromLocalDateAndReferenceTime(baseEntitlementWithAddOnsSpecifier.getBillingEffectiveDate(), now, contextWithSourceAccountRecordId);
+ final DateTime requestedDate = dateHelper.fromLocalDateAndReferenceTime(baseEntitlementWithAddOnsSpecifier.getBillingEffectiveDate(), updatedPluginContext.getCreatedDate(), contextWithSourceAccountRecordId);
final SubscriptionBaseBundle newBundle = subscriptionBaseTransferApi.transferBundle(sourceAccountId, destAccountId, externalKey, requestedDate, true, cancelImm, context);
@@ -494,7 +487,7 @@ public class DefaultEntitlementApi extends DefaultEntitlementApiBase implements
final InternalCallContext contextWithDestAccountRecordId = internalCallContextFactory.createInternalCallContext(destAccountId, context);
blockingStates.clear();
- final DateTime entitlementRequestedDate = dateHelper.fromLocalDateAndReferenceTime(baseEntitlementWithAddOnsSpecifier.getEntitlementEffectiveDate(), now, contextWithDestAccountRecordId);
+ final DateTime entitlementRequestedDate = dateHelper.fromLocalDateAndReferenceTime(baseEntitlementWithAddOnsSpecifier.getEntitlementEffectiveDate(), updatedPluginContext.getCreatedDate(), contextWithDestAccountRecordId);
for (final SubscriptionBase subscriptionBase : subscriptionBaseInternalApi.getSubscriptionsForBundle(newBundle.getId(), null, contextWithDestAccountRecordId)) {
final BlockingState newBlockingState = new DefaultBlockingState(subscriptionBase.getId(), BlockingStateType.SUBSCRIPTION, DefaultEntitlementApi.ENT_STATE_START, EntitlementService.ENTITLEMENT_SERVICE_NAME, false, false, false, entitlementRequestedDate);
blockingStates.put(newBlockingState, 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 a9691ee..2178510 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
@@ -287,7 +287,7 @@ public class DefaultSubscriptionApi implements SubscriptionApi {
}
- final LocalDate effectiveDate = internalCallContext.toLocalDate(clock.getUTCNow());
+ final LocalDate effectiveDate = internalCallContext.toLocalDate(callContext.getCreatedDate());
final BaseEntitlementWithAddOnsSpecifier baseEntitlementWithAddOnsSpecifier = new DefaultBaseEntitlementWithAddOnsSpecifier(
bundleId,
newExternalKey,
@@ -375,7 +375,7 @@ public class DefaultSubscriptionApi implements SubscriptionApi {
throw new EntitlementApiException(e);
}
- final DateTime effectiveDate = inputEffectiveDate == null ? clock.getUTCNow() : internalCallContextWithValidAccountId.toUTCDateTime(inputEffectiveDate);
+ final DateTime effectiveDate = inputEffectiveDate == null ? callContext.getCreatedDate() : internalCallContextWithValidAccountId.toUTCDateTime(inputEffectiveDate);
final DefaultBlockingState blockingState = new DefaultBlockingState(inputBlockingState, effectiveDate);
final BaseEntitlementWithAddOnsSpecifier baseEntitlementWithAddOnsSpecifier = new DefaultBaseEntitlementWithAddOnsSpecifier(
diff --git a/entitlement/src/main/java/org/killbill/billing/entitlement/api/svcs/DefaultEntitlementApiBase.java b/entitlement/src/main/java/org/killbill/billing/entitlement/api/svcs/DefaultEntitlementApiBase.java
index 169c38a..e73bdad 100644
--- a/entitlement/src/main/java/org/killbill/billing/entitlement/api/svcs/DefaultEntitlementApiBase.java
+++ b/entitlement/src/main/java/org/killbill/billing/entitlement/api/svcs/DefaultEntitlementApiBase.java
@@ -209,8 +209,7 @@ public class DefaultEntitlementApiBase {
private UUID blockUnblockBundle(final UUID bundleId, final String stateName, final String serviceName, @Nullable final LocalDate localEffectiveDate, boolean blockBilling, boolean blockEntitlement, boolean blockChange, @Nullable final SubscriptionBase inputBaseSubscription, final InternalCallContext internalCallContext)
throws EntitlementApiException {
- final DateTime now = clock.getUTCNow();
- final DateTime effectiveDate = dateHelper.fromLocalDateAndReferenceTime(localEffectiveDate, now, internalCallContext);
+ final DateTime effectiveDate = dateHelper.fromLocalDateAndReferenceTime(localEffectiveDate, internalCallContext.getCreatedDate(), internalCallContext);
final BlockingState state = new DefaultBlockingState(bundleId, BlockingStateType.SUBSCRIPTION_BUNDLE, stateName, serviceName, blockChange, blockEntitlement, blockBilling, effectiveDate);
entitlementUtils.setBlockingStatesAndPostBlockingTransitionEvent(ImmutableList.<BlockingState>of(state), bundleId, internalCallContext);
return state.getId();
diff --git a/entitlement/src/main/java/org/killbill/billing/entitlement/api/svcs/DefaultEntitlementInternalApi.java b/entitlement/src/main/java/org/killbill/billing/entitlement/api/svcs/DefaultEntitlementInternalApi.java
index 7e91ad9..0b69332 100644
--- a/entitlement/src/main/java/org/killbill/billing/entitlement/api/svcs/DefaultEntitlementInternalApi.java
+++ b/entitlement/src/main/java/org/killbill/billing/entitlement/api/svcs/DefaultEntitlementInternalApi.java
@@ -234,8 +234,7 @@ public class DefaultEntitlementInternalApi extends DefaultEntitlementApiBase imp
@Override
public Entitlement doCall(final EntitlementApi entitlementApi, final EntitlementContext updatedPluginContext) throws EntitlementApiException {
- final DateTime now = clock.getUTCNow();
- DateTime effectiveDate = dateHelper.fromLocalDateAndReferenceTime(updatedPluginContext.getBaseEntitlementWithAddOnsSpecifiers().iterator().next().getEntitlementEffectiveDate(), now, internalCallContext);
+ DateTime effectiveDate = dateHelper.fromLocalDateAndReferenceTime(updatedPluginContext.getBaseEntitlementWithAddOnsSpecifiers().iterator().next().getEntitlementEffectiveDate(), updatedPluginContext.getCreatedDate(), internalCallContext);
//
// If the entitlementDate provided is ahead we default to the effective subscriptionBase cancellationDate to avoid weird timing issues.
diff --git a/entitlement/src/main/java/org/killbill/billing/entitlement/dao/DefaultBlockingStateDao.java b/entitlement/src/main/java/org/killbill/billing/entitlement/dao/DefaultBlockingStateDao.java
index 7bda51f..68660ff 100644
--- a/entitlement/src/main/java/org/killbill/billing/entitlement/dao/DefaultBlockingStateDao.java
+++ b/entitlement/src/main/java/org/killbill/billing/entitlement/dao/DefaultBlockingStateDao.java
@@ -298,7 +298,7 @@ public class DefaultBlockingStateDao extends EntityDaoBase<BlockingStateModelDao
final boolean isTransitionToBlockedEntitlement = !previousState.isBlockEntitlement() && currentState.isBlockEntitlement();
final boolean isTransitionToUnblockedEntitlement = previousState.isBlockEntitlement() && !currentState.isBlockEntitlement();
- if (effectiveDate.compareTo(clock.getUTCNow()) > 0) {
+ if (effectiveDate.compareTo(context.getCreatedDate()) > 0) {
// Add notification entry to send the bus event at the effective date
final NotificationEvent notificationEvent = new BlockingTransitionNotificationKey(blockingStateId,
blockableId,
diff --git a/entitlement/src/main/java/org/killbill/billing/entitlement/logging/EntitlementLoggingHelper.java b/entitlement/src/main/java/org/killbill/billing/entitlement/logging/EntitlementLoggingHelper.java
index a0b158c..3039f4c 100644
--- a/entitlement/src/main/java/org/killbill/billing/entitlement/logging/EntitlementLoggingHelper.java
+++ b/entitlement/src/main/java/org/killbill/billing/entitlement/logging/EntitlementLoggingHelper.java
@@ -74,8 +74,9 @@ public abstract class EntitlementLoggingHelper {
final StringBuilder logLine = new StringBuilder("Create Entitlements with AddOns: ");
if (baseEntitlementSpecifiersWithAddOns != null && baseEntitlementSpecifiersWithAddOns.iterator().hasNext()) {
- for (BaseEntitlementWithAddOnsSpecifier cur : baseEntitlementSpecifiersWithAddOns) {
- logCreateEntitlementWithAOs(log, cur.getExternalKey(),
+ for (final BaseEntitlementWithAddOnsSpecifier cur : baseEntitlementSpecifiersWithAddOns) {
+ logCreateEntitlementWithAOs(logLine,
+ cur.getExternalKey(),
cur.getEntitlementSpecifier(),
cur.getEntitlementEffectiveDate(),
cur.getBillingEffectiveDate());
@@ -85,33 +86,27 @@ public abstract class EntitlementLoggingHelper {
}
}
- public static void logCreateEntitlementWithAOs(final Logger log,
- final String externalKey,
- final Iterable<EntitlementSpecifier> entitlementSpecifiers,
- final LocalDate entitlementDate,
- final LocalDate billingDate) {
- if (log.isInfoEnabled()) {
- final StringBuilder logLine = new StringBuilder("Create Entitlements: ");
-
- if (externalKey != null) {
- logLine.append("key='")
- .append(externalKey)
- .append("'");
- }
- if (entitlementDate != null) {
- logLine.append(", entDate='")
- .append(entitlementDate)
- .append("'");
- }
- if (billingDate != null) {
- logLine.append(", billDate='")
- .append(billingDate)
- .append("'");
- }
- logEntitlementSpecifier(logLine, entitlementSpecifiers);
- log.info(logLine.toString());
+ private static void logCreateEntitlementWithAOs(final StringBuilder logLine,
+ final String externalKey,
+ final Iterable<EntitlementSpecifier> entitlementSpecifiers,
+ final LocalDate entitlementDate,
+ final LocalDate billingDate) {
+ if (externalKey != null) {
+ logLine.append("key='")
+ .append(externalKey)
+ .append("'");
}
-
+ if (entitlementDate != null) {
+ logLine.append(", entDate='")
+ .append(entitlementDate)
+ .append("'");
+ }
+ if (billingDate != null) {
+ logLine.append(", billDate='")
+ .append(billingDate)
+ .append("'");
+ }
+ logEntitlementSpecifier(logLine, entitlementSpecifiers);
}
public static void logPauseResumeEntitlement(final Logger log,
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/dao/DefaultInvoiceDao.java b/invoice/src/main/java/org/killbill/billing/invoice/dao/DefaultInvoiceDao.java
index 1283805..e8acdde 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/dao/DefaultInvoiceDao.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/dao/DefaultInvoiceDao.java
@@ -1142,11 +1142,10 @@ public class DefaultInvoiceDao extends EntityDaoBase<InvoiceModelDao, Invoice, I
private void notifyOfParentInvoiceCreation(final EntitySqlDaoWrapperFactory entitySqlDaoWrapperFactory,
final InvoiceModelDao parentInvoice,
final InternalCallContext context) {
- final DateTime now = clock.getUTCNow();
final LocalTime localTime = LocalTime.parse(invoiceConfig.getParentAutoCommitUtcTime(context));
- DateTime targetFutureNotificationDate = now.withTime(localTime);
- while (targetFutureNotificationDate.compareTo(now) < 0) {
+ DateTime targetFutureNotificationDate = context.getCreatedDate().withTime(localTime);
+ while (targetFutureNotificationDate.compareTo(context.getCreatedDate()) < 0) {
targetFutureNotificationDate = targetFutureNotificationDate.plusDays(1);
}
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/generator/FixedAndRecurringInvoiceItemGenerator.java b/invoice/src/main/java/org/killbill/billing/invoice/generator/FixedAndRecurringInvoiceItemGenerator.java
index c73adba..0fd86a0 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/generator/FixedAndRecurringInvoiceItemGenerator.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/generator/FixedAndRecurringInvoiceItemGenerator.java
@@ -412,7 +412,7 @@ public class FixedAndRecurringInvoiceItemGenerator extends InvoiceItemGenerator
}
@VisibleForTesting
- void safetyBounds(final Iterable<InvoiceItem> resultingItems, final Multimap<UUID, LocalDate> createdItemsPerDayPerSubscription, final InternalTenantContext internalCallContext) throws InvoiceApiException {
+ void safetyBounds(final Iterable<InvoiceItem> resultingItems, final Multimap<UUID, LocalDate> createdItemsPerDayPerSubscription, final InternalCallContext internalCallContext) throws InvoiceApiException {
// Trigger an exception if we detect the creation of similar items for a given subscription
// See https://github.com/killbill/killbill/issues/664
if (config.isSanitySafetyBoundEnabled(internalCallContext)) {
@@ -472,13 +472,13 @@ public class FixedAndRecurringInvoiceItemGenerator extends InvoiceItemGenerator
}
}
- private LocalDate trackInvoiceItemCreatedDay(final InvoiceItem invoiceItem, final Multimap<UUID, LocalDate> createdItemsPerDayPerSubscription, final InternalTenantContext internalCallContext) {
+ private LocalDate trackInvoiceItemCreatedDay(final InvoiceItem invoiceItem, final Multimap<UUID, LocalDate> createdItemsPerDayPerSubscription, final InternalCallContext internalCallContext) {
final UUID subscriptionId = invoiceItem.getSubscriptionId();
if (subscriptionId == null) {
return null;
}
- final LocalDate createdDay = internalCallContext.toLocalDate(MoreObjects.firstNonNull(invoiceItem.getCreatedDate(), clock.getUTCNow()));
+ final LocalDate createdDay = internalCallContext.toLocalDate(MoreObjects.firstNonNull(invoiceItem.getCreatedDate(), internalCallContext.getCreatedDate()));
createdItemsPerDayPerSubscription.put(subscriptionId, createdDay);
return createdDay;
}
diff --git a/invoice/src/test/java/org/killbill/billing/invoice/InvoiceTestSuiteWithEmbeddedDB.java b/invoice/src/test/java/org/killbill/billing/invoice/InvoiceTestSuiteWithEmbeddedDB.java
index f5eceaa..f0789e8 100644
--- a/invoice/src/test/java/org/killbill/billing/invoice/InvoiceTestSuiteWithEmbeddedDB.java
+++ b/invoice/src/test/java/org/killbill/billing/invoice/InvoiceTestSuiteWithEmbeddedDB.java
@@ -92,8 +92,6 @@ public abstract class InvoiceTestSuiteWithEmbeddedDB extends GuicyKillbillTestSu
@Inject
protected GlobalLocker locker;
@Inject
- protected ClockMock clock;
- @Inject
protected InternalCallContextFactory internalCallContextFactory;
@Inject
protected InvoiceInternalApi invoiceInternalApi;
diff --git a/invoice/src/test/java/org/killbill/billing/invoice/proRations/InvoiceTestUtils.java b/invoice/src/test/java/org/killbill/billing/invoice/proRations/InvoiceTestUtils.java
index 42fccdb..92bce8a 100644
--- a/invoice/src/test/java/org/killbill/billing/invoice/proRations/InvoiceTestUtils.java
+++ b/invoice/src/test/java/org/killbill/billing/invoice/proRations/InvoiceTestUtils.java
@@ -23,6 +23,8 @@ import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
+import org.joda.time.DateTime;
+import org.joda.time.LocalDate;
import org.killbill.billing.account.api.Account;
import org.killbill.billing.account.api.AccountApiException;
import org.killbill.billing.callcontext.InternalCallContext;
@@ -88,8 +90,9 @@ public class InvoiceTestUtils {
Mockito.when(invoice.getId()).thenReturn(invoiceId);
Mockito.when(invoice.getAccountId()).thenReturn(accountId);
- Mockito.when(invoice.getInvoiceDate()).thenReturn(clock.getUTCToday());
- Mockito.when(invoice.getTargetDate()).thenReturn(clock.getUTCToday());
+ final LocalDate today = clock.getUTCToday();
+ Mockito.when(invoice.getInvoiceDate()).thenReturn(today);
+ Mockito.when(invoice.getTargetDate()).thenReturn(today);
Mockito.when(invoice.getCurrency()).thenReturn(currency);
Mockito.when(invoice.isMigrationInvoice()).thenReturn(false);
Mockito.when(invoice.getStatus()).thenReturn(InvoiceStatus.COMMITTED);
@@ -127,7 +130,8 @@ public class InvoiceTestUtils {
Mockito.when(payment.getInvoiceId()).thenReturn(invoiceId);
Mockito.when(payment.getPaymentId()).thenReturn(UUID.randomUUID());
Mockito.when(payment.getPaymentCookieId()).thenReturn(UUID.randomUUID().toString());
- Mockito.when(payment.getPaymentDate()).thenReturn(clock.getUTCNow());
+ final DateTime utcNow = clock.getUTCNow();
+ Mockito.when(payment.getPaymentDate()).thenReturn(utcNow);
Mockito.when(payment.getAmount()).thenReturn(amount);
Mockito.when(payment.getCurrency()).thenReturn(currency);
Mockito.when(payment.getProcessedCurrency()).thenReturn(currency);
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/BulkSubscriptionsBundleJson.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/BulkSubscriptionsBundleJson.java
index 4066056..faaf0fb 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/BulkSubscriptionsBundleJson.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/BulkSubscriptionsBundleJson.java
@@ -32,8 +32,7 @@ public class BulkSubscriptionsBundleJson {
private final List<SubscriptionJson> baseEntitlementAndAddOns;
@JsonCreator
- public BulkSubscriptionsBundleJson(
- @JsonProperty("baseEntitlementAndAddOns") @Nullable final List<SubscriptionJson> baseEntitlementAndAddOns) {
+ public BulkSubscriptionsBundleJson(@JsonProperty("baseEntitlementAndAddOns") @Nullable final List<SubscriptionJson> baseEntitlementAndAddOns) {
this.baseEntitlementAndAddOns = baseEntitlementAndAddOns;
}
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/CreditResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/CreditResource.java
index 27558a0..d590177 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/CreditResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/CreditResource.java
@@ -120,7 +120,7 @@ public class CreditResource extends JaxRsResourceBase {
final CallContext callContext = context.createCallContextNoAccountId(createdBy, reason, comment, request);
final Account account = accountUserApi.getAccountById(json.getAccountId(), callContext);
- final LocalDate effectiveDate = new LocalDate(clock.getUTCNow(), account.getTimeZone());
+ final LocalDate effectiveDate = new LocalDate(callContext.getCreatedDate(), account.getTimeZone());
final InvoiceItem credit;
if (json.getInvoiceId() != null) {
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 7fdf952..35f7c60 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
@@ -57,7 +57,6 @@ import org.killbill.billing.catalog.api.Currency;
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.entitlement.api.BaseEntitlementWithAddOnsSpecifier;
import org.killbill.billing.entitlement.api.BlockingStateType;
import org.killbill.billing.entitlement.api.Entitlement;
@@ -107,8 +106,6 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.base.Preconditions;
-import com.google.common.base.Predicate;
-import com.google.common.collect.Collections2;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import com.google.inject.Inject;
@@ -187,75 +184,8 @@ public class SubscriptionResource extends JaxRsResourceBase {
@HeaderParam(HDR_COMMENT) final String comment,
@javax.ws.rs.core.Context final HttpServletRequest request,
@javax.ws.rs.core.Context final UriInfo uriInfo) throws EntitlementApiException, AccountApiException, SubscriptionApiException {
- verifyNonNullOrEmpty(entitlement, "SubscriptionJson body should be specified");
- if (entitlement.getPlanName() == null) {
- verifyNonNullOrEmpty(entitlement.getProductName(), "SubscriptionJson productName needs to be set",
- entitlement.getProductCategory(), "SubscriptionJson productCategory needs to be set",
- entitlement.getBillingPeriod(), "SubscriptionJson billingPeriod needs to be set",
- entitlement.getPriceList(), "SubscriptionJson priceList needs to be set");
- }
-
- logDeprecationParameterWarningIfNeeded(QUERY_REQUESTED_DT, QUERY_ENTITLEMENT_REQUESTED_DT, QUERY_BILLING_REQUESTED_DT);
-
- // For ADD_ON we need to provide externalKey or the bundleId
- if (ProductCategory.ADD_ON.toString().equals(entitlement.getProductCategory())) {
- Preconditions.checkArgument(entitlement.getExternalKey() != null || entitlement.getBundleId() != null, "SubscriptionJson bundleId or externalKey should be specified for ADD_ON");
- }
-
- 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<UUID> callback = new EntitlementCallCompletionCallback<UUID>() {
- @Override
- 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;
- final PlanPhaseSpecifier spec = entitlement.getPlanName() != null ?
- new PlanPhaseSpecifier(entitlement.getPlanName(), phaseType) :
- new PlanPhaseSpecifier(entitlement.getProductName(),
- BillingPeriod.valueOf(entitlement.getBillingPeriod()), entitlement.getPriceList(), phaseType);
-
- 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 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) {
- final Entitlement createdEntitlement = entitlementApi.getEntitlementForId(result, callContext);
- createdEntitlement.updateBCD(newBCD, null, callContext);
- }
- return result;
- }
-
- private UUID getBundleIdForAddOnCreation(final SubscriptionJson entitlement) throws SubscriptionApiException {
-
- if (entitlement.getBundleId() != null) {
- return entitlement.getBundleId();
- }
- // If user only specified the externalKey we need to fech the bundle (expensive operation) to extract the bundleId
- final SubscriptionBundle bundle = subscriptionApi.getActiveSubscriptionBundleForExternalKey(entitlement.getExternalKey(), callContext);
- return bundle.getId();
- }
-
- @Override
- public boolean isImmOperation() {
- return true;
- }
-
- @Override
- public Response doResponseOk(final UUID createdEntitlementId) {
- return uriBuilder.buildResponse(uriInfo, SubscriptionResource.class, "getEntitlement", createdEntitlementId, request);
- }
- };
-
- final EntitlementCallCompletion<UUID> callCompletionCreation = new EntitlementCallCompletion<UUID>();
- return callCompletionCreation.withSynchronization(callback, timeoutSec, callCompletion, callContext);
+ final List<BulkSubscriptionsBundleJson> entitlementsWithAddOns = ImmutableList.of(new BulkSubscriptionsBundleJson(ImmutableList.<SubscriptionJson>of(entitlement)));
+ return createEntitlementsWithAddOnsInternal(entitlementsWithAddOns, requestedDate, entitlementDate, billingDate, isMigrated, renameKeyIfExistsAndUnused, callCompletion, timeoutSec, pluginPropertiesString, createdBy, reason, comment, request, uriInfo, ObjectType.SUBSCRIPTION);
}
@TimedResource
@@ -322,60 +252,57 @@ public class SubscriptionResource extends JaxRsResourceBase {
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.");
+ Preconditions.checkArgument(Iterables.size(entitlementsWithAddOns) > 0, "No subscription specified to create");
logDeprecationParameterWarningIfNeeded(QUERY_REQUESTED_DT, QUERY_ENTITLEMENT_REQUESTED_DT, QUERY_BILLING_REQUESTED_DT);
final Iterable<PluginProperty> pluginProperties = extractPluginProperties(pluginPropertiesString);
final CallContext callContext = context.createCallContextNoAccountId(createdBy, reason, comment, request);
+ Preconditions.checkArgument(Iterables.size(entitlementsWithAddOns.get(0).getBaseEntitlementAndAddOns()) > 0, "SubscriptionJson body should be specified");
final Account account = accountUserApi.getAccountById(entitlementsWithAddOns.get(0).getBaseEntitlementAndAddOns().get(0).getAccountId(), callContext);
final Collection<BaseEntitlementWithAddOnsSpecifier> baseEntitlementWithAddOnsSpecifierList = new ArrayList<BaseEntitlementWithAddOnsSpecifier>();
- for (final BulkSubscriptionsBundleJson bulkBaseEntitlementWithAddOns : entitlementsWithAddOns) {
- final Iterable<SubscriptionJson> baseEntitlements = Iterables.filter(
- bulkBaseEntitlementWithAddOns.getBaseEntitlementAndAddOns(), new Predicate<SubscriptionJson>() {
- @Override
- public boolean apply(final SubscriptionJson subscription) {
- return ProductCategory.BASE.toString().equalsIgnoreCase(subscription.getProductCategory());
- }
- });
-
- final List<EntitlementSpecifier> entitlementSpecifierList;
- final String bundleExternalKey;
- if (baseEntitlements.iterator().hasNext()) {
- Preconditions.checkArgument(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
- public boolean apply(final SubscriptionJson subscription) {
- return ProductCategory.ADD_ON.toString().equalsIgnoreCase(subscription.getProductCategory());
- }
- });
-
- entitlementSpecifierList = buildEntitlementSpecifierList(baseEntitlement, addonEntitlements, account.getCurrency());
- bundleExternalKey = baseEntitlement.getExternalKey();
- } else {
- final Collection<SubscriptionJson> standaloneEntitlements = Collections2.filter(bulkBaseEntitlementWithAddOns.getBaseEntitlementAndAddOns(),
- new Predicate<SubscriptionJson>() {
- @Override
- public boolean apply(final SubscriptionJson subscription) {
- return ProductCategory.STANDALONE.toString().equalsIgnoreCase(subscription.getProductCategory());
- }
- });
- entitlementSpecifierList = buildEntitlementSpecifierList(standaloneEntitlements, account.getCurrency());
- bundleExternalKey = standaloneEntitlements.isEmpty() ? null : standaloneEntitlements.iterator().next().getExternalKey();
+ for (final BulkSubscriptionsBundleJson subscriptionsBundleJson : entitlementsWithAddOns) {
+ UUID bundleId = null;
+ String bundleExternalKey = null;
+ final Collection<EntitlementSpecifier> entitlementSpecifierList = new ArrayList<EntitlementSpecifier>();
+ for (final SubscriptionJson entitlement : subscriptionsBundleJson.getBaseEntitlementAndAddOns()) {
+ // verifications
+ verifyNonNullOrEmpty(entitlement, "SubscriptionJson body should be specified for each element");
+ if (entitlement.getPlanName() == null) {
+ verifyNonNullOrEmpty(entitlement.getProductName(), "SubscriptionJson productName needs to be set when no planName is specified",
+ entitlement.getProductCategory(), "SubscriptionJson productCategory needs to be set when no planName is specified",
+ entitlement.getBillingPeriod(), "SubscriptionJson billingPeriod needs to be set when no planName is specified",
+ entitlement.getPriceList(), "SubscriptionJson priceList needs to be set when no planName is specified");
+ } else {
+ Preconditions.checkArgument(entitlement.getProductName() == null, "SubscriptionJson productName should not be set when planName is specified");
+ Preconditions.checkArgument(entitlement.getProductCategory() == null, "SubscriptionJson productCategory should not be set when planName is specified");
+ Preconditions.checkArgument(entitlement.getBillingPeriod() == null, "SubscriptionJson billingPeriod should not be set when planName is specified");
+ Preconditions.checkArgument(entitlement.getPriceList() == null, "SubscriptionJson priceList should not be set when planName is specified");
+ }
+ Preconditions.checkArgument(account.getId().equals(entitlement.getAccountId()), "SubscriptionJson accountId should be the same for each element");
+ // If set on one element, it should be set on all elements
+ Preconditions.checkArgument(bundleId == null || bundleId.equals(entitlement.getBundleId()), "SubscriptionJson bundleId should be the same for each element");
+ if (bundleId == null) {
+ bundleId = entitlement.getBundleId();
+ }
+ // Can be set on a single element (e.g. BASE + ADD_ON for a new bundle)
+ Preconditions.checkArgument(bundleExternalKey == null || entitlement.getExternalKey() == null || bundleExternalKey.equals(entitlement.getExternalKey()), "SubscriptionJson externalKey should be the same for each element");
+ if (bundleExternalKey == null) {
+ bundleExternalKey = entitlement.getExternalKey();
+ }
+ // create the entitlementSpecifier
+ buildEntitlementSpecifier(entitlement, account.getCurrency(), entitlementSpecifierList);
}
- // create the baseEntitlementSpecifierWithAddOns
final LocalDate resolvedEntitlementDate = requestedDate != null ? toLocalDate(requestedDate) : toLocalDate(entitlementDate);
final LocalDate resolvedBillingDate = requestedDate != null ? toLocalDate(requestedDate) : toLocalDate(billingDate);
final BaseEntitlementWithAddOnsSpecifier baseEntitlementSpecifierWithAddOns = buildBaseEntitlementWithAddOnsSpecifier(entitlementSpecifierList,
resolvedEntitlementDate,
resolvedBillingDate,
+ bundleId,
bundleExternalKey,
isMigrated);
baseEntitlementWithAddOnsSpecifierList.add(baseEntitlementSpecifierWithAddOns);
@@ -383,7 +310,7 @@ public class SubscriptionResource extends JaxRsResourceBase {
final EntitlementCallCompletionCallback<List<UUID>> callback = new EntitlementCallCompletionCallback<List<UUID>>() {
@Override
- public List<UUID> doOperation(final CallContext ctx) throws InterruptedException, TimeoutException, EntitlementApiException, SubscriptionApiException, AccountApiException {
+ public List<UUID> doOperation(final CallContext ctx) throws EntitlementApiException {
return entitlementApi.createBaseEntitlementsWithAddOns(account.getId(), baseEntitlementWithAddOnsSpecifierList, renameKeyIfExistsAndUnused, pluginProperties, callContext);
}
@@ -394,6 +321,10 @@ public class SubscriptionResource extends JaxRsResourceBase {
@Override
public Response doResponseOk(final List<UUID> entitlementIds) {
+ if (responseObject == ObjectType.SUBSCRIPTION) {
+ return uriBuilder.buildResponse(uriInfo, SubscriptionResource.class, "getEntitlement", Iterables.getFirst(entitlementIds, null), request);
+ }
+
final Collection<String> bundleIds = new LinkedHashSet<String>();
try {
for (final Entitlement entitlement : entitlementApi.getAllEntitlementsForAccountId(account.getId(), callContext)) {
@@ -418,50 +349,6 @@ public class SubscriptionResource extends JaxRsResourceBase {
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>();
-
- //
- // BASE or STANDALONE is fully specified, we can add it
- //
- buildEntitlementSpecifier(baseEntitlement, currency, entitlementSpecifierList);
-
- for (final SubscriptionJson entitlement : addonEntitlements) {
- // verifications
- verifyNonNullOrEmpty(entitlement, "SubscriptionJson body should be specified for each element");
- if (entitlement.getPlanName() == null) {
- verifyNonNullOrEmpty(entitlement.getProductName(), "SubscriptionJson productName needs to be set for each element",
- entitlement.getProductCategory(), "SubscriptionJson productCategory needs to be set for each element",
- entitlement.getBillingPeriod(), "SubscriptionJson billingPeriod needs to be set for each element",
- entitlement.getPriceList(), "SubscriptionJson priceList needs to be set for each element");
- }
- // create the entitlementSpecifier
- buildEntitlementSpecifier(entitlement, currency, entitlementSpecifierList);
- }
- return entitlementSpecifierList;
- }
-
- private List<EntitlementSpecifier> buildEntitlementSpecifierList(final Iterable<SubscriptionJson> standaloneEntitlements,
- final Currency currency) {
- final List<EntitlementSpecifier> entitlementSpecifierList = new ArrayList<EntitlementSpecifier>();
-
- for (final SubscriptionJson standaloneEntitlement : standaloneEntitlements) {
- // verifications
- verifyNonNullOrEmpty(standaloneEntitlement, "SubscriptionJson body should be specified for each element");
- if (standaloneEntitlement.getPlanName() == null) {
- verifyNonNullOrEmpty(standaloneEntitlement.getProductName(), "SubscriptionJson productName needs to be set for each element",
- standaloneEntitlement.getProductCategory(), "SubscriptionJson productCategory needs to be set for each element",
- standaloneEntitlement.getBillingPeriod(), "SubscriptionJson billingPeriod needs to be set for each element",
- standaloneEntitlement.getPriceList(), "SubscriptionJson priceList needs to be set for each element");
- }
- // create the entitlementSpecifier
- buildEntitlementSpecifier(standaloneEntitlement, currency, entitlementSpecifierList);
- }
- return entitlementSpecifierList;
- }
-
private void buildEntitlementSpecifier(final SubscriptionJson subscriptionJson,
final Currency currency,
final Collection<EntitlementSpecifier> entitlementSpecifierList) {
@@ -478,7 +365,7 @@ public class SubscriptionResource extends JaxRsResourceBase {
new PlanPhaseSpecifier(subscriptionJson.getProductName(),
BillingPeriod.valueOf(subscriptionJson.getBillingPeriod()),
subscriptionJson.getPriceList(),
- null);
+ subscriptionJson.getPhaseType() == null ? null : PhaseType.valueOf(subscriptionJson.getPhaseType()));
final List<PlanPhasePriceOverride> overrides = PhasePriceOverrideJson.toPlanPhasePriceOverrides(subscriptionJson.getPriceOverrides(),
planPhaseSpecifier,
currency);
@@ -500,12 +387,13 @@ public class SubscriptionResource extends JaxRsResourceBase {
private BaseEntitlementWithAddOnsSpecifier buildBaseEntitlementWithAddOnsSpecifier(final Iterable<EntitlementSpecifier> entitlementSpecifierList,
final LocalDate resolvedEntitlementDate,
final LocalDate resolvedBillingDate,
+ @Nullable final UUID bundleId,
@Nullable final String bundleExternalKey,
final Boolean isMigrated) {
return new BaseEntitlementWithAddOnsSpecifier() {
@Override
public UUID getBundleId() {
- return null;
+ return bundleId;
}
@Override
@@ -619,8 +507,8 @@ public class SubscriptionResource extends JaxRsResourceBase {
private boolean isImmediateOp = true;
@Override
- public Response doOperation(final CallContext ctx) throws EntitlementApiException, InterruptedException,
- TimeoutException, AccountApiException {
+ public Response doOperation(final CallContext ctx) throws EntitlementApiException,
+ AccountApiException {
final Entitlement current = entitlementApi.getEntitlementForId(subscriptionId, callContext);
final LocalDate inputLocalDate = toLocalDate(requestedDate);
@@ -714,8 +602,8 @@ public class SubscriptionResource extends JaxRsResourceBase {
@Override
public Response doOperation(final CallContext ctx)
- throws EntitlementApiException, InterruptedException,
- TimeoutException, AccountApiException, SubscriptionApiException {
+ throws EntitlementApiException,
+ SubscriptionApiException {
final Entitlement current = entitlementApi.getEntitlementForId(subscriptionId, ctx);
final LocalDate inputLocalDate = toLocalDate(requestedDate);
final Entitlement newEntitlement;
@@ -735,7 +623,7 @@ public class SubscriptionResource extends JaxRsResourceBase {
final Subscription subscription = subscriptionApi.getSubscriptionForEntitlementId(newEntitlement.getId(), ctx);
- final LocalDate nowInAccountTimeZone = new LocalDate(clock.getUTCNow(), subscription.getBillingEndDate().getChronology().getZone());
+ final LocalDate nowInAccountTimeZone = new LocalDate(callContext.getCreatedDate(), subscription.getBillingEndDate().getChronology().getZone());
isImmediateOp = subscription.getBillingEndDate() != null &&
!subscription.getBillingEndDate().isAfter(nowInAccountTimeZone);
return Response.status(Status.OK).build();
@@ -771,7 +659,7 @@ public class SubscriptionResource extends JaxRsResourceBase {
@HeaderParam(HDR_REASON) final String reason,
@HeaderParam(HDR_COMMENT) final String comment,
@javax.ws.rs.core.Context final UriInfo uriInfo,
- @javax.ws.rs.core.Context final HttpServletRequest request) throws SubscriptionApiException, EntitlementApiException, AccountApiException {
+ @javax.ws.rs.core.Context final HttpServletRequest request) throws EntitlementApiException, AccountApiException {
verifyNonNullOrEmpty(json, "SubscriptionJson body should be specified");
verifyNonNullOrEmpty(json.getBillCycleDayLocal(), "SubscriptionJson new BCD should be specified");
@@ -782,7 +670,7 @@ public class SubscriptionResource extends JaxRsResourceBase {
final Entitlement entitlement = entitlementApi.getEntitlementForId(subscriptionId, callContext);
if (effectiveFromDateStr != null) {
final Account account = accountUserApi.getAccountById(entitlement.getAccountId(), callContext);
- final LocalDate accountToday = new LocalDate(clock.getUTCNow(), account.getTimeZone());
+ final LocalDate accountToday = new LocalDate(callContext.getCreatedDate(), account.getTimeZone());
int comp = effectiveFromDate.compareTo(accountToday);
switch (comp) {
case -1:
@@ -869,11 +757,11 @@ public class SubscriptionResource extends JaxRsResourceBase {
private interface EntitlementCallCompletionCallback<T> {
- public T doOperation(final CallContext ctx) throws EntitlementApiException, InterruptedException, TimeoutException, AccountApiException, SubscriptionApiException;
+ T doOperation(final CallContext ctx) throws EntitlementApiException, InterruptedException, TimeoutException, AccountApiException, SubscriptionApiException;
- public boolean isImmOperation();
+ boolean isImmOperation();
- public Response doResponseOk(final T operationResponse) throws SubscriptionApiException, AccountApiException, CatalogApiException;
+ Response doResponseOk(final T operationResponse) throws SubscriptionApiException, AccountApiException, CatalogApiException;
}
private class EntitlementCallCompletion<T> {
diff --git a/jaxrs/src/test/java/org/killbill/billing/jaxrs/json/TestInvoiceItemJsonSimple.java b/jaxrs/src/test/java/org/killbill/billing/jaxrs/json/TestInvoiceItemJsonSimple.java
index 833b874..c852acd 100644
--- a/jaxrs/src/test/java/org/killbill/billing/jaxrs/json/TestInvoiceItemJsonSimple.java
+++ b/jaxrs/src/test/java/org/killbill/billing/jaxrs/json/TestInvoiceItemJsonSimple.java
@@ -93,8 +93,9 @@ public class TestInvoiceItemJsonSimple extends JaxrsTestSuiteNoDB {
Mockito.when(invoiceItem.getPhaseName()).thenReturn(UUID.randomUUID().toString());
Mockito.when(invoiceItem.getUsageName()).thenReturn(UUID.randomUUID().toString());
Mockito.when(invoiceItem.getDescription()).thenReturn(UUID.randomUUID().toString());
- Mockito.when(invoiceItem.getStartDate()).thenReturn(clock.getUTCToday());
- Mockito.when(invoiceItem.getEndDate()).thenReturn(clock.getUTCToday());
+ final LocalDate utcToday = clock.getUTCToday();
+ Mockito.when(invoiceItem.getStartDate()).thenReturn(utcToday);
+ Mockito.when(invoiceItem.getEndDate()).thenReturn(utcToday);
Mockito.when(invoiceItem.getAmount()).thenReturn(BigDecimal.TEN);
Mockito.when(invoiceItem.getCurrency()).thenReturn(Currency.EUR);
Mockito.when(invoiceItem.getInvoiceItemType()).thenReturn(InvoiceItemType.FIXED);
diff --git a/jaxrs/src/test/java/org/killbill/billing/jaxrs/json/TestInvoiceJsonWithBundleKeys.java b/jaxrs/src/test/java/org/killbill/billing/jaxrs/json/TestInvoiceJsonWithBundleKeys.java
index 67df93d..df58a0e 100644
--- a/jaxrs/src/test/java/org/killbill/billing/jaxrs/json/TestInvoiceJsonWithBundleKeys.java
+++ b/jaxrs/src/test/java/org/killbill/billing/jaxrs/json/TestInvoiceJsonWithBundleKeys.java
@@ -84,8 +84,9 @@ public class TestInvoiceJsonWithBundleKeys extends JaxrsTestSuiteNoDB {
Mockito.when(invoice.getCreditedAmount()).thenReturn(BigDecimal.ONE);
Mockito.when(invoice.getRefundedAmount()).thenReturn(BigDecimal.ONE);
Mockito.when(invoice.getId()).thenReturn(UUID.randomUUID());
- Mockito.when(invoice.getInvoiceDate()).thenReturn(clock.getUTCToday());
- Mockito.when(invoice.getTargetDate()).thenReturn(clock.getUTCToday());
+ final LocalDate utcToday = clock.getUTCToday();
+ Mockito.when(invoice.getInvoiceDate()).thenReturn(utcToday);
+ Mockito.when(invoice.getTargetDate()).thenReturn(utcToday);
Mockito.when(invoice.getInvoiceNumber()).thenReturn(Integer.MAX_VALUE);
Mockito.when(invoice.getBalance()).thenReturn(BigDecimal.ZERO);
Mockito.when(invoice.getAccountId()).thenReturn(UUID.randomUUID());
diff --git a/overdue/src/main/java/org/killbill/billing/overdue/calculator/BillingStateCalculator.java b/overdue/src/main/java/org/killbill/billing/overdue/calculator/BillingStateCalculator.java
index 5c2a254..a9b1632 100644
--- a/overdue/src/main/java/org/killbill/billing/overdue/calculator/BillingStateCalculator.java
+++ b/overdue/src/main/java/org/killbill/billing/overdue/calculator/BillingStateCalculator.java
@@ -30,6 +30,7 @@ import java.util.UUID;
import org.joda.time.LocalDate;
import org.killbill.billing.ObjectType;
import org.killbill.billing.account.api.ImmutableAccountData;
+import org.killbill.billing.callcontext.InternalCallContext;
import org.killbill.billing.callcontext.InternalTenantContext;
import org.killbill.billing.invoice.api.Invoice;
import org.killbill.billing.invoice.api.InvoiceInternalApi;
@@ -68,7 +69,7 @@ public class BillingStateCalculator {
this.tagApi = tagApi;
}
- public BillingState calculateBillingState(final ImmutableAccountData account, final InternalTenantContext context) throws OverdueException {
+ public BillingState calculateBillingState(final ImmutableAccountData account, final InternalCallContext context) throws OverdueException {
final SortedSet<Invoice> unpaidInvoices = unpaidInvoicesForAccount(account.getId(), context);
final int numberOfUnpaidInvoices = unpaidInvoices.size();
@@ -104,8 +105,8 @@ public class BillingStateCalculator {
return sum;
}
- SortedSet<Invoice> unpaidInvoicesForAccount(final UUID accountId, final InternalTenantContext context) {
- final Collection<Invoice> invoices = invoiceApi.getUnpaidInvoicesByAccountId(accountId, context.toLocalDate(clock.getUTCNow()), context);
+ SortedSet<Invoice> unpaidInvoicesForAccount(final UUID accountId, final InternalCallContext context) {
+ final Collection<Invoice> invoices = invoiceApi.getUnpaidInvoicesByAccountId(accountId, context.toLocalDate(context.getCreatedDate()), context);
final SortedSet<Invoice> sortedInvoices = new TreeSet<Invoice>(new InvoiceDateComparator());
sortedInvoices.addAll(invoices);
return sortedInvoices;
diff --git a/overdue/src/main/java/org/killbill/billing/overdue/listener/OverdueListener.java b/overdue/src/main/java/org/killbill/billing/overdue/listener/OverdueListener.java
index 8bed766..7ecdb5c 100644
--- a/overdue/src/main/java/org/killbill/billing/overdue/listener/OverdueListener.java
+++ b/overdue/src/main/java/org/killbill/billing/overdue/listener/OverdueListener.java
@@ -155,7 +155,7 @@ public class OverdueListener {
if (shouldInsertNotification) {
OverdueAsyncBusNotificationKey notificationKey = new OverdueAsyncBusNotificationKey(accountId, action);
- asyncPoster.insertOverdueNotification(accountId, clock.getUTCNow(), OverdueAsyncBusNotifier.OVERDUE_ASYNC_BUS_NOTIFIER_QUEUE, notificationKey, callContext);
+ asyncPoster.insertOverdueNotification(accountId, callContext.getCreatedDate(), OverdueAsyncBusNotifier.OVERDUE_ASYNC_BUS_NOTIFIER_QUEUE, notificationKey, callContext);
try {
final List<Account> childrenAccounts = accountApi.getChildrenAccounts(accountId, callContext);
@@ -166,7 +166,7 @@ public class OverdueListener {
final InternalTenantContext internalTenantContext = internalCallContextFactory.createInternalTenantContext(childAccount.getId(), callContext);
final InternalCallContext accountContext = internalCallContextFactory.createInternalCallContext(internalTenantContext.getAccountRecordId(), callContext);
notificationKey = new OverdueAsyncBusNotificationKey(childAccount.getId(), action);
- asyncPoster.insertOverdueNotification(childAccount.getId(), clock.getUTCNow(), OverdueAsyncBusNotifier.OVERDUE_ASYNC_BUS_NOTIFIER_QUEUE, notificationKey, accountContext);
+ asyncPoster.insertOverdueNotification(childAccount.getId(), callContext.getCreatedDate(), OverdueAsyncBusNotifier.OVERDUE_ASYNC_BUS_NOTIFIER_QUEUE, notificationKey, accountContext);
}
}
}
diff --git a/overdue/src/main/java/org/killbill/billing/overdue/wrapper/OverdueWrapper.java b/overdue/src/main/java/org/killbill/billing/overdue/wrapper/OverdueWrapper.java
index 11481f9..750ad19 100644
--- a/overdue/src/main/java/org/killbill/billing/overdue/wrapper/OverdueWrapper.java
+++ b/overdue/src/main/java/org/killbill/billing/overdue/wrapper/OverdueWrapper.java
@@ -104,7 +104,7 @@ public class OverdueWrapper {
final BlockingState blockingStateForService = api.getBlockingStateForService(overdueable.getId(), BlockingStateType.ACCOUNT, OverdueService.OVERDUE_SERVICE_NAME, context);
final String previousOverdueStateName = blockingStateForService != null ? blockingStateForService.getStateName() : OverdueWrapper.CLEAR_STATE_NAME;
final OverdueState currentOverdueState = overdueStateSet.findState(previousOverdueStateName);
- final OverdueState nextOverdueState = overdueStateSet.calculateOverdueState(billingState, context.toLocalDate(clock.getUTCNow()));
+ final OverdueState nextOverdueState = overdueStateSet.calculateOverdueState(billingState, context.toLocalDate(context.getCreatedDate()));
overdueStateApplicator.apply(effectiveDate, overdueStateSet, billingState, overdueable, currentOverdueState, nextOverdueState, context);
diff --git a/overdue/src/test/java/org/killbill/billing/overdue/calculator/TestBillingStateCalculator.java b/overdue/src/test/java/org/killbill/billing/overdue/calculator/TestBillingStateCalculator.java
index 0ac1feb..598f22d 100644
--- a/overdue/src/test/java/org/killbill/billing/overdue/calculator/TestBillingStateCalculator.java
+++ b/overdue/src/test/java/org/killbill/billing/overdue/calculator/TestBillingStateCalculator.java
@@ -26,6 +26,7 @@ import java.util.UUID;
import org.joda.time.DateTimeZone;
import org.joda.time.LocalDate;
import org.killbill.billing.account.api.ImmutableAccountData;
+import org.killbill.billing.callcontext.InternalCallContext;
import org.mockito.Mockito;
import org.testng.Assert;
import org.testng.annotations.BeforeMethod;
@@ -63,7 +64,7 @@ public class TestBillingStateCalculator extends OverdueTestSuiteNoDB {
return new BillingStateCalculator(invoiceApi, clock, tagInternalApi) {
@Override
public BillingState calculateBillingState(final ImmutableAccountData overdueable,
- final InternalTenantContext context) {
+ final InternalCallContext context) {
return null;
}
};
diff --git a/payment/src/main/java/org/killbill/billing/payment/core/janitor/IncompletePaymentTransactionTask.java b/payment/src/main/java/org/killbill/billing/payment/core/janitor/IncompletePaymentTransactionTask.java
index 1e101e1..ff535d7 100644
--- a/payment/src/main/java/org/killbill/billing/payment/core/janitor/IncompletePaymentTransactionTask.java
+++ b/payment/src/main/java/org/killbill/billing/payment/core/janitor/IncompletePaymentTransactionTask.java
@@ -276,13 +276,13 @@ public class IncompletePaymentTransactionTask extends CompletionTaskBase<Payment
}
@VisibleForTesting
- DateTime getNextNotificationTime(final TransactionStatus transactionStatus, final Integer attemptNumber, final InternalTenantContext tenantContext) {
+ DateTime getNextNotificationTime(final TransactionStatus transactionStatus, final Integer attemptNumber, final InternalTenantContext internalTenantContext) {
final List<TimeSpan> retries;
if (TransactionStatus.UNKNOWN.equals(transactionStatus)) {
- retries = paymentConfig.getUnknownTransactionsRetries(tenantContext);
+ retries = paymentConfig.getUnknownTransactionsRetries(internalTenantContext);
} else if (TransactionStatus.PENDING.equals(transactionStatus)) {
- retries = paymentConfig.getPendingTransactionsRetries(tenantContext);
+ retries = paymentConfig.getPendingTransactionsRetries(internalTenantContext);
} else {
retries = ImmutableList.of();
log.warn("Unexpected transactionStatus='{}' from janitor, ignore...", transactionStatus);
diff --git a/payment/src/main/java/org/killbill/billing/payment/core/sm/PaymentAutomatonRunner.java b/payment/src/main/java/org/killbill/billing/payment/core/sm/PaymentAutomatonRunner.java
index 109d91e..3098a97 100644
--- a/payment/src/main/java/org/killbill/billing/payment/core/sm/PaymentAutomatonRunner.java
+++ b/payment/src/main/java/org/killbill/billing/payment/core/sm/PaymentAutomatonRunner.java
@@ -157,7 +157,7 @@ public class PaymentAutomatonRunner {
public PaymentAutomatonDAOHelper buildDaoHelper(final PaymentStateContext paymentStateContext,
final InternalCallContext internalCallContext) throws PaymentApiException {
- final DateTime utcNow = clock.getUTCNow();
+ final DateTime utcNow = internalCallContext.getCreatedDate();
return new PaymentAutomatonDAOHelper(paymentStateContext, utcNow, paymentDao, paymentPluginServiceRegistration, internalCallContext, eventBus, paymentSMHelper);
}
diff --git a/payment/src/main/java/org/killbill/billing/payment/dao/DefaultPaymentDao.java b/payment/src/main/java/org/killbill/billing/payment/dao/DefaultPaymentDao.java
index 7ab31a6..114744a 100644
--- a/payment/src/main/java/org/killbill/billing/payment/dao/DefaultPaymentDao.java
+++ b/payment/src/main/java/org/killbill/billing/payment/dao/DefaultPaymentDao.java
@@ -398,7 +398,7 @@ public class DefaultPaymentDao extends EntityDaoBase<PaymentModelDao, Payment, P
}
paymentAndTransactionModelDao.setPaymentModelDao(paymentModelDao);
- postPaymentEventFromTransaction(accountId, transactionStatus, transactionType, paymentId, transactionId, processedAmount, processedCurrency, clock.getUTCNow(), gatewayErrorCode, entitySqlDaoWrapperFactory, context);
+ postPaymentEventFromTransaction(accountId, transactionStatus, transactionType, paymentId, transactionId, processedAmount, processedCurrency, contextWithUpdatedDate.getCreatedDate(), gatewayErrorCode, entitySqlDaoWrapperFactory, context);
return paymentAndTransactionModelDao;
}
@@ -731,7 +731,7 @@ public class DefaultPaymentDao extends EntityDaoBase<PaymentModelDao, Payment, P
}
private InternalCallContext contextWithUpdatedDate(final InternalCallContext input) {
- return new InternalCallContext(input, clock.getUTCNow());
+ return new InternalCallContext(input, input.getCreatedDate());
}
@Override
diff --git a/payment/src/main/java/org/killbill/billing/payment/invoice/InvoicePaymentControlPluginApi.java b/payment/src/main/java/org/killbill/billing/payment/invoice/InvoicePaymentControlPluginApi.java
index dced1af..d87a2f0 100644
--- a/payment/src/main/java/org/killbill/billing/payment/invoice/InvoicePaymentControlPluginApi.java
+++ b/payment/src/main/java/org/killbill/billing/payment/invoice/InvoicePaymentControlPluginApi.java
@@ -297,7 +297,7 @@ public final class InvoicePaymentControlPluginApi implements PaymentControlPlugi
final List<PluginAutoPayOffModelDao> entries = controlDao.getAutoPayOffEntry(accountId);
for (final PluginAutoPayOffModelDao cur : entries) {
// TODO In theory we should pass not only PLUGIN_NAME, but also all the plugin list associated which the original call
- retryServiceScheduler.scheduleRetry(ObjectType.ACCOUNT, accountId, cur.getAttemptId(), internalCallContext.getTenantRecordId(), ImmutableList.<String>of(PLUGIN_NAME), clock.getUTCNow());
+ retryServiceScheduler.scheduleRetry(ObjectType.ACCOUNT, accountId, cur.getAttemptId(), internalCallContext.getTenantRecordId(), ImmutableList.<String>of(PLUGIN_NAME), internalCallContext.getCreatedDate());
}
controlDao.removeAutoPayOffEntry(accountId);
}
@@ -522,11 +522,11 @@ public final class InvoicePaymentControlPluginApi implements PaymentControlPlugi
final int retryCount = (attemptsInState - 1) >= 0 ? (attemptsInState - 1) : 0;
if (retryCount < retryDays.size()) {
final int retryInDays;
- final DateTime nextRetryDate = clock.getUTCNow();
+ final DateTime nextRetryDate = internalContext.getCreatedDate();
try {
retryInDays = retryDays.get(retryCount);
result = nextRetryDate.plusDays(retryInDays);
- log.debug("Next retryDate={}, retryInDays={}, retryCount={}, now={}", result, retryInDays, retryCount, clock.getUTCNow());
+ log.debug("Next retryDate={}, retryInDays={}, retryCount={}, now={}", result, retryInDays, retryCount, internalContext.getCreatedDate());
} catch (final NumberFormatException ex) {
log.error("Could not get retry day for retry count {}", retryCount);
}
@@ -546,8 +546,8 @@ public final class InvoicePaymentControlPluginApi implements PaymentControlPlugi
while (--remainingAttempts > 0) {
nbSec = nbSec * paymentConfig.getPluginFailureRetryMultiplier(internalContext);
}
- result = clock.getUTCNow().plusSeconds(nbSec);
- log.debug("Next retryDate={}, retryAttempt={}, now={}", result, retryAttempt, clock.getUTCNow());
+ result = internalContext.getCreatedDate().plusSeconds(nbSec);
+ log.debug("Next retryDate={}, retryAttempt={}, now={}", result, retryAttempt, internalContext.getCreatedDate());
}
return result;
}
@@ -674,7 +674,7 @@ public final class InvoicePaymentControlPluginApi implements PaymentControlPlugi
final PluginAutoPayOffModelDao data = new PluginAutoPayOffModelDao(paymentControlContext.getAttemptPaymentId(), paymentControlContext.getPaymentExternalKey(), paymentControlContext.getTransactionExternalKey(),
paymentControlContext.getAccountId(), PLUGIN_NAME,
paymentControlContext.getPaymentId(), paymentControlContext.getPaymentMethodId(),
- computedAmount, paymentControlContext.getCurrency(), CREATED_BY, clock.getUTCNow());
+ computedAmount, paymentControlContext.getCurrency(), CREATED_BY, paymentControlContext.getCreatedDate());
controlDao.insertAutoPayOff(data);
return true;
}
diff --git a/payment/src/main/java/org/killbill/billing/payment/provider/ExternalPaymentProviderPlugin.java b/payment/src/main/java/org/killbill/billing/payment/provider/ExternalPaymentProviderPlugin.java
index db8a69e..5871b80 100644
--- a/payment/src/main/java/org/killbill/billing/payment/provider/ExternalPaymentProviderPlugin.java
+++ b/payment/src/main/java/org/killbill/billing/payment/provider/ExternalPaymentProviderPlugin.java
@@ -65,27 +65,27 @@ public class ExternalPaymentProviderPlugin implements PaymentPluginApi {
@Override
public PaymentTransactionInfoPlugin authorizePayment(final UUID kbAccountId, final UUID kbPaymentId, final UUID kbTransactionId, final UUID kbPaymentMethodId, final BigDecimal amount, final Currency currency, final Iterable<PluginProperty> properties, final CallContext callContext) throws PaymentPluginApiException {
- return new DefaultNoOpPaymentInfoPlugin(kbPaymentId, kbTransactionId, TransactionType.AUTHORIZE, amount, currency, clock.getUTCNow(), clock.getUTCNow(), getPaymentPluginStatus(properties), null, null);
+ return new DefaultNoOpPaymentInfoPlugin(kbPaymentId, kbTransactionId, TransactionType.AUTHORIZE, amount, currency, callContext.getCreatedDate(), callContext.getCreatedDate(), getPaymentPluginStatus(properties), null, null);
}
@Override
public PaymentTransactionInfoPlugin capturePayment(final UUID kbAccountId, final UUID kbPaymentId, final UUID kbTransactionId, final UUID kbPaymentMethodId, final BigDecimal amount, final Currency currency, final Iterable<PluginProperty> properties, final CallContext callContext) throws PaymentPluginApiException {
- return new DefaultNoOpPaymentInfoPlugin(kbPaymentId, kbTransactionId, TransactionType.CAPTURE, amount, currency, clock.getUTCNow(), clock.getUTCNow(), getPaymentPluginStatus(properties), null, null);
+ return new DefaultNoOpPaymentInfoPlugin(kbPaymentId, kbTransactionId, TransactionType.CAPTURE, amount, currency, callContext.getCreatedDate(), callContext.getCreatedDate(), getPaymentPluginStatus(properties), null, null);
}
@Override
public PaymentTransactionInfoPlugin purchasePayment(final UUID kbAccountId, final UUID kbPaymentId, final UUID kbTransactionId, final UUID kbPaymentMethodId, final BigDecimal amount, final Currency currency, final Iterable<PluginProperty> properties, final CallContext context) throws PaymentPluginApiException {
- return new DefaultNoOpPaymentInfoPlugin(kbPaymentId, kbTransactionId, TransactionType.PURCHASE, amount, currency, clock.getUTCNow(), clock.getUTCNow(), getPaymentPluginStatus(properties), null, null);
+ return new DefaultNoOpPaymentInfoPlugin(kbPaymentId, kbTransactionId, TransactionType.PURCHASE, amount, currency, context.getCreatedDate(), context.getCreatedDate(), getPaymentPluginStatus(properties), null, null);
}
@Override
public PaymentTransactionInfoPlugin voidPayment(final UUID kbAccountId, final UUID kbPaymentId, final UUID kbTransactionId, final UUID kbPaymentMethodId, final Iterable<PluginProperty> properties, final CallContext callContext) throws PaymentPluginApiException {
- return new DefaultNoOpPaymentInfoPlugin(kbPaymentId, kbTransactionId, TransactionType.VOID, BigDecimal.ZERO, null, clock.getUTCNow(), clock.getUTCNow(), getPaymentPluginStatus(properties), null, null);
+ return new DefaultNoOpPaymentInfoPlugin(kbPaymentId, kbTransactionId, TransactionType.VOID, BigDecimal.ZERO, null, callContext.getCreatedDate(), callContext.getCreatedDate(), getPaymentPluginStatus(properties), null, null);
}
@Override
public PaymentTransactionInfoPlugin creditPayment(final UUID kbAccountId, final UUID kbPaymentId, final UUID kbTransactionId, final UUID kbPaymentMethodId, final BigDecimal amount, final Currency currency, final Iterable<PluginProperty> properties, final CallContext callContext) throws PaymentPluginApiException {
- return new DefaultNoOpPaymentInfoPlugin(kbPaymentId, kbTransactionId, TransactionType.CREDIT, amount, currency, clock.getUTCNow(), clock.getUTCNow(), getPaymentPluginStatus(properties), null, null);
+ return new DefaultNoOpPaymentInfoPlugin(kbPaymentId, kbTransactionId, TransactionType.CREDIT, amount, currency, callContext.getCreatedDate(), callContext.getCreatedDate(), getPaymentPluginStatus(properties), null, null);
}
@Override
@@ -100,7 +100,7 @@ public class ExternalPaymentProviderPlugin implements PaymentPluginApi {
@Override
public PaymentTransactionInfoPlugin refundPayment(final UUID kbAccountId, final UUID kbPaymentId, final UUID kbTransactionId, final UUID kbPaymentMethodId, final BigDecimal refundAmount, final Currency currency, final Iterable<PluginProperty> properties, final CallContext context) throws PaymentPluginApiException {
- return new DefaultNoOpPaymentInfoPlugin(kbPaymentId, kbTransactionId, TransactionType.REFUND, refundAmount, currency, clock.getUTCNow(), clock.getUTCNow(), getPaymentPluginStatus(properties), null, null);
+ return new DefaultNoOpPaymentInfoPlugin(kbPaymentId, kbTransactionId, TransactionType.REFUND, refundAmount, currency, context.getCreatedDate(), context.getCreatedDate(), getPaymentPluginStatus(properties), null, null);
}
@Override
diff --git a/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestEntitlement.java b/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestEntitlement.java
index 899ca00..021e62c 100644
--- a/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestEntitlement.java
+++ b/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestEntitlement.java
@@ -344,7 +344,6 @@ public class TestEntitlement extends TestJaxrsBase {
final Subscription addOn1 = new Subscription();
addOn1.setAccountId(accountJson.getAccountId());
- addOn1.setExternalKey("");
addOn1.setProductName("Telescopic-Scope");
addOn1.setProductCategory(ProductCategory.ADD_ON);
addOn1.setBillingPeriod(BillingPeriod.MONTHLY);
@@ -352,7 +351,6 @@ public class TestEntitlement extends TestJaxrsBase {
final Subscription addOn2 = new Subscription();
addOn2.setAccountId(accountJson.getAccountId());
- addOn2.setExternalKey("");
addOn2.setProductName("Laser-Scope");
addOn2.setProductCategory(ProductCategory.ADD_ON);
addOn2.setBillingPeriod(BillingPeriod.MONTHLY);
@@ -466,7 +464,7 @@ public class TestEntitlement extends TestJaxrsBase {
}
@Test(groups = "slow", description = "Create a bulk of base entitlements and addOns under the same transaction",
- expectedExceptions = KillBillClientException.class, expectedExceptionsMessageRegExp = "Missing Base Subscription for bundle 12345")
+ expectedExceptions = KillBillClientException.class, expectedExceptionsMessageRegExp = "SubscriptionJson productName needs to be set when no planName is specified")
public void testCreateEntitlementsWithoutBase() throws Exception {
final DateTime initialDate = new DateTime(2012, 4, 25, 0, 3, 42, 0);
clock.setDeltaFromReality(initialDate.getMillis() - clock.getUTCNow().getMillis());
@@ -496,7 +494,7 @@ public class TestEntitlement extends TestJaxrsBase {
killBillClient.createSubscriptionsWithAddOns(bulkList, null, 10, requestOptions);
}
- @Test(groups = "slow", description = "Create addOns in a bundle where BP subscrsiptions already exist")
+ @Test(groups = "slow", description = "Create addOns in a bundle where BP subscription already exists")
public void testEntitlementsWithAddOnsAndAlreadyExistingBP() throws Exception {
final DateTime initialDate = new DateTime(2012, 4, 25, 0, 3, 42, 0);
clock.setDeltaFromReality(initialDate.getMillis() - clock.getUTCNow().getMillis());
@@ -512,13 +510,9 @@ public class TestEntitlement extends TestJaxrsBase {
input.setPriceList(PriceListSet.DEFAULT_PRICELIST_NAME);
final Subscription subscription = killBillClient.createSubscription(input, null, DEFAULT_WAIT_COMPLETION_TIMEOUT_SEC, requestOptions);
- final Subscription base = new Subscription();
- base.setAccountId(accountJson.getAccountId());
- base.setProductCategory(ProductCategory.BASE);
- base.setExternalKey("foobarxyz");
-
final Subscription addOn1 = new Subscription();
addOn1.setAccountId(accountJson.getAccountId());
+ addOn1.setBundleId(subscription.getBundleId());
addOn1.setProductName("Telescopic-Scope");
addOn1.setProductCategory(ProductCategory.ADD_ON);
addOn1.setBillingPeriod(BillingPeriod.MONTHLY);
@@ -526,13 +520,13 @@ public class TestEntitlement extends TestJaxrsBase {
final Subscription addOn2 = new Subscription();
addOn2.setAccountId(accountJson.getAccountId());
+ addOn2.setBundleId(subscription.getBundleId());
addOn2.setProductName("Laser-Scope");
addOn2.setProductCategory(ProductCategory.ADD_ON);
addOn2.setBillingPeriod(BillingPeriod.MONTHLY);
addOn2.setPriceList(PriceListSet.DEFAULT_PRICELIST_NAME);
final List<Subscription> subscriptions = new ArrayList<Subscription>();
- subscriptions.add(base);
subscriptions.add(addOn1);
subscriptions.add(addOn2);
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 9794ac6..10a2b1b 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
@@ -275,11 +275,11 @@ public class DefaultSubscriptionInternalApi extends SubscriptionApiBase implemen
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 SubscriptionBaseWithAddOnsSpecifier subscriptionBaseWithAddOnsSpecifier : subscriptionWithAddOnsSpecifiers) {
- final DateTime billingRequestedDateRaw = subscriptionBaseWithAddOnsSpecifier.getBillingEffectiveDate() != null ? subscriptionBaseWithAddOnsSpecifier.getBillingEffectiveDate() : now;
+ final DateTime billingRequestedDateRaw = (subscriptionBaseWithAddOnsSpecifier.getBillingEffectiveDate() != null) ?
+ context.toUTCDateTime(subscriptionBaseWithAddOnsSpecifier.getBillingEffectiveDate()) : context.getCreatedDate();
final Collection<EntitlementSpecifier> reorderedSpecifiers = new ArrayList<EntitlementSpecifier>();
// Note: billingRequestedDateRaw might not be accurate here (add-on with a too early date passed)?
@@ -323,6 +323,7 @@ public class DefaultSubscriptionInternalApi extends SubscriptionApiBase implemen
} else if (bundle != null && baseSubscription != null && baseOrFirstStandalonePlanSpecifier != null && isBaseSpecifier(catalog, billingRequestedDateRaw, baseOrFirstStandalonePlanSpecifier)) {
throw new SubscriptionBaseApiException(ErrorCode.SUB_CREATE_BP_EXISTS, bundle.getExternalKey());
} else if (bundle == null) {
+ log.warn("Invalid specifier: {}", subscriptionBaseWithAddOnsSpecifier);
throw new SubscriptionBaseApiException(ErrorCode.SUB_CREATE_INVALID_ENTITLEMENT_SPECIFIER);
}
@@ -333,7 +334,7 @@ public class DefaultSubscriptionInternalApi extends SubscriptionApiBase implemen
reorderedSpecifiers,
subscriptionBaseWithAddOnsSpecifier.isMigrated(),
context,
- now,
+ context.getCreatedDate(),
billingRequestedDate,
catalog,
callContext));
@@ -400,7 +401,7 @@ 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 DateTime now = context.getCreatedDate();
final DefaultSubscriptionBaseBundle bundle = new DefaultSubscriptionBaseBundle(bundleKey, accountId, now, now, now, now);
if (null != bundleKey && bundleKey.length() > 255) {
throw new SubscriptionBaseApiException(ErrorCode.EXTERNAL_KEY_LIMIT_EXCEEDED);
@@ -614,9 +615,8 @@ public class DefaultSubscriptionInternalApi extends SubscriptionApiBase implemen
// verify the number of subscriptions (of the same kind) allowed per bundle
final Catalog catalog = catalogInternalApi.getFullCatalog(true, true, context);
- final DateTime now = clock.getUTCNow();
final DateTime effectiveDate = (requestedDateWithMs != null) ? DefaultClock.truncateMs(requestedDateWithMs) : null;
- final DateTime effectiveCatalogDate = effectiveDate != null ? effectiveDate : now;
+ final DateTime effectiveCatalogDate = effectiveDate != null ? effectiveDate : context.getCreatedDate();
final PlanPhasePriceOverridesWithCallContext overridesWithContext = new DefaultPlanPhasePriceOverridesWithCallContext(overrides, callContext);
final Plan plan = catalog.createOrFindPlan(spec, overridesWithContext, effectiveCatalogDate);
if (ProductCategory.ADD_ON.toString().equalsIgnoreCase(plan.getProduct().getCategory().toString())) {
@@ -877,7 +877,7 @@ public class DefaultSubscriptionInternalApi extends SubscriptionApiBase implemen
}
// Today as seen by this account
- final LocalDate startDate = effectiveFromDate != null ? effectiveFromDate : internalCallContext.toLocalDate(clock.getUTCNow());
+ final LocalDate startDate = effectiveFromDate != null ? effectiveFromDate : internalCallContext.toLocalDate(internalCallContext.getCreatedDate());
// We want to compute a LocalDate in account TZ which maps to the provided 'bcd' and then compute an effectiveDate for when that BCD_CHANGE event needs to be triggered
//
@@ -899,7 +899,7 @@ public class DefaultSubscriptionInternalApi extends SubscriptionApiBase implemen
} else /* bcd > lastDayOfMonth && bcd > currentDay */ {
requestedDate = new LocalDate(startDate.getYear(), startDate.getMonthOfYear(), lastDayOfMonth);
}
- return requestedDate == null ? clock.getUTCNow() : internalCallContext.toUTCDateTime(requestedDate);
+ return requestedDate == null ? internalCallContext.getCreatedDate() : internalCallContext.toUTCDateTime(requestedDate);
}
private DateTime getBundleStartDateWithSanity(final UUID bundleId, @Nullable final SubscriptionBase baseSubscription, final Plan plan,
diff --git a/subscription/src/main/java/org/killbill/billing/subscription/api/transfer/DefaultSubscriptionBaseTransferApi.java b/subscription/src/main/java/org/killbill/billing/subscription/api/transfer/DefaultSubscriptionBaseTransferApi.java
index f93883e..2d73917 100644
--- a/subscription/src/main/java/org/killbill/billing/subscription/api/transfer/DefaultSubscriptionBaseTransferApi.java
+++ b/subscription/src/main/java/org/killbill/billing/subscription/api/transfer/DefaultSubscriptionBaseTransferApi.java
@@ -181,13 +181,12 @@ public class DefaultSubscriptionBaseTransferApi extends SubscriptionApiBase impl
final InternalCallContext fromInternalCallContext = internalCallContextFactory.createInternalCallContext(sourceAccountId, context);
final InternalCallContext toInternalCallContext = internalCallContextFactory.createInternalCallContext(destAccountId, context);
-
try {
final Catalog catalog = catalogInternalApi.getFullCatalog(true, true, fromInternalCallContext);
- final DateTime effectiveTransferDate = transferDate == null ? clock.getUTCNow() : transferDate;
- if (effectiveTransferDate.isAfter(clock.getUTCNow())) {
+ final DateTime effectiveTransferDate = transferDate == null ? context.getCreatedDate() : transferDate;
+ if (effectiveTransferDate.isAfter(context.getCreatedDate())) {
// The transfer event for the migrated bundle will be the first one, which cannot be in the future
// (subscription always expects the first event to be in the past)
throw new SubscriptionBaseTransferApiException(ErrorCode.SUB_TRANSFER_INVALID_EFF_DATE, effectiveTransferDate);
@@ -204,7 +203,7 @@ public class DefaultSubscriptionBaseTransferApi extends SubscriptionApiBase impl
final BundleBaseTimeline bundleBaseTimeline = timelineApi.getBundleTimeline(bundle, context);
final DefaultSubscriptionBaseBundle subscriptionBundleData = new DefaultSubscriptionBaseBundle(bundleKey, destAccountId, effectiveTransferDate,
- bundle.getOriginalCreatedDate(), clock.getUTCNow(), clock.getUTCNow());
+ bundle.getOriginalCreatedDate(), context.getCreatedDate(), context.getCreatedDate());
final List<SubscriptionTransferData> subscriptionTransferDataList = new LinkedList<SubscriptionTransferData>();
final List<TransferCancelData> transferCancelDataList = new LinkedList<TransferCancelData>();
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 29cedce..6f3b516 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
@@ -167,7 +167,6 @@ public class DefaultSubscriptionBaseApiService implements SubscriptionBaseApiSer
if (currentState == EntitlementState.CANCELLED) {
throw new SubscriptionBaseApiException(ErrorCode.SUB_CANCEL_BAD_STATE, subscription.getId(), currentState);
}
- final DateTime now = clock.getUTCNow();
final Plan currentPlan = subscription.getCurrentOrPendingPlan();
final PlanPhaseSpecifier planPhase = new PlanPhaseSpecifier(currentPlan.getName(), null);
@@ -197,8 +196,7 @@ public class DefaultSubscriptionBaseApiService implements SubscriptionBaseApiSer
final Catalog fullCatalog;
try {
fullCatalog = catalogInternalApi.getFullCatalog(true, true, internalCallContext);
- final DateTime now = clock.getUTCNow();
- final DateTime effectiveDate = (requestedDateWithMs != null) ? DefaultClock.truncateMs(requestedDateWithMs) : now;
+ final DateTime effectiveDate = (requestedDateWithMs != null) ? DefaultClock.truncateMs(requestedDateWithMs) : context.getCreatedDate();
return doCancelPlan(ImmutableMap.<DefaultSubscriptionBase, DateTime>of(subscription, effectiveDate), fullCatalog, internalCallContext);
} catch (final CatalogApiException e) {
@@ -280,10 +278,9 @@ public class DefaultSubscriptionBaseApiService implements SubscriptionBaseApiSer
final InternalCallContext internalCallContext = createCallContextFromBundleId(subscription.getBundleId(), context);
final Catalog fullCatalog = catalogInternalApi.getFullCatalog(true, true, internalCallContext);
- final DateTime now = clock.getUTCNow();
final SubscriptionBaseEvent uncancelEvent = new ApiEventUncancel(new ApiEventBuilder()
.setSubscriptionId(subscription.getId())
- .setEffectiveDate(now)
+ .setEffectiveDate(context.getCreatedDate())
.setFromDisk(true));
final List<SubscriptionBaseEvent> uncancelEvents = new ArrayList<SubscriptionBaseEvent>();
@@ -294,7 +291,7 @@ public class DefaultSubscriptionBaseApiService implements SubscriptionBaseApiSer
// In case of a pending subscription we don't want to pass an effective date prior the CREATE event as we would end up with the wrong
// transition in PlanAligner (next transition would be CREATE instead of potential next PHASE)
//
- final DateTime planAlignerEffectiveDate = subscription.getState() == EntitlementState.PENDING ? subscription.getStartDate() : now;
+ final DateTime planAlignerEffectiveDate = subscription.getState() == EntitlementState.PENDING ? subscription.getStartDate() : context.getCreatedDate();
final TimedPhase nextTimedPhase = planAligner.getNextTimedPhase(subscription, planAlignerEffectiveDate, fullCatalog, internalCallContext);
final PhaseEvent nextPhaseEvent = (nextTimedPhase != null) ?
@@ -337,11 +334,9 @@ public class DefaultSubscriptionBaseApiService implements SubscriptionBaseApiSer
@Override
public DateTime changePlan(final DefaultSubscriptionBase subscription, final PlanPhaseSpecifier spec, final List<PlanPhasePriceOverride> overrides, final CallContext context) throws SubscriptionBaseApiException {
- final DateTime now = clock.getUTCNow();
-
validateSubscriptionStateForChangePlan(subscription, null);
- final PlanChangeResult planChangeResult = getPlanChangeResult(subscription, spec, now, context);
+ final PlanChangeResult planChangeResult = getPlanChangeResult(subscription, spec, context.getCreatedDate(), context);
final DateTime effectiveDate = dryRunChangePlan(subscription, spec, null, planChangeResult.getPolicy(), context);
validateEffectiveDate(subscription, effectiveDate);
@@ -562,10 +557,9 @@ public class DefaultSubscriptionBaseApiService implements SubscriptionBaseApiSer
final InternalCallContext internalCallContext = createCallContextFromBundleId(subscription.getBundleId(), context);
final Catalog fullCatalog = catalogInternalApi.getFullCatalog(true, true, internalCallContext);
- final DateTime now = clock.getUTCNow();
final SubscriptionBaseEvent undoChangePlanEvent = new ApiEventUndoChange(new ApiEventBuilder()
.setSubscriptionId(subscription.getId())
- .setEffectiveDate(now)
+ .setEffectiveDate(context.getCreatedDate())
.setFromDisk(true));
final List<SubscriptionBaseEvent> undoChangePlanEvents = new ArrayList<SubscriptionBaseEvent>();
@@ -576,7 +570,7 @@ public class DefaultSubscriptionBaseApiService implements SubscriptionBaseApiSer
// In case of a pending subscription we don't want to pass an effective date prior the CREATE event as we would end up with the wrong
// transition in PlanAligner (next transition would be CREATE instead of potential next PHASE)
//
- final DateTime planAlignerEffectiveDate = subscription.getState() == EntitlementState.PENDING ? subscription.getStartDate() : now;
+ final DateTime planAlignerEffectiveDate = subscription.getState() == EntitlementState.PENDING ? subscription.getStartDate() : context.getCreatedDate();
final TimedPhase nextTimedPhase = planAligner.getNextTimedPhase(subscription, planAlignerEffectiveDate, fullCatalog, internalCallContext);
final PhaseEvent nextPhaseEvent = (nextTimedPhase != null) ?
@@ -614,8 +608,7 @@ public class DefaultSubscriptionBaseApiService implements SubscriptionBaseApiSer
private List<DefaultSubscriptionBase> computeAddOnsToCancel(final Collection<SubscriptionBaseEvent> cancelEvents, final CatalogEntity baseProduct, final UUID bundleId, final DateTime effectiveDate, final Catalog catalog, final InternalCallContext internalCallContext) throws CatalogApiException {
// If cancellation/change occur in the future, there is nothing to do
- final DateTime now = clock.getUTCNow();
- if (effectiveDate.compareTo(now) > 0) {
+ if (effectiveDate.compareTo(internalCallContext.getCreatedDate()) > 0) {
return ImmutableList.<DefaultSubscriptionBase>of();
} else {
return addCancellationAddOnForEventsIfRequired(cancelEvents, baseProduct, bundleId, effectiveDate, catalog, internalCallContext);
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 065e0c8..98ed638 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
@@ -471,7 +471,7 @@ public class DefaultSubscriptionDao extends EntityDaoBase<SubscriptionBundleMode
final BundleSqlDao bundleSqlDao = entitySqlDaoWrapperFactory.become(BundleSqlDao.class);
final String bundleId = subscription.getBundleId().toString();
- bundleSqlDao.updateBundleLastSysTime(bundleId, clock.getUTCNow().toDate(), contextWithUpdatedDate);
+ bundleSqlDao.updateBundleLastSysTime(bundleId, context.getCreatedDate().toDate(), contextWithUpdatedDate);
return null;
}
});
@@ -553,7 +553,7 @@ public class DefaultSubscriptionDao extends EntityDaoBase<SubscriptionBundleMode
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);
+ final boolean isBusEvent = cur.getEffectiveDate().compareTo(context.getCreatedDate()) <= 0 && (cur.getType() == EventType.API_USER);
recordBusOrFutureNotificationFromTransaction(defaultSubscriptionBase, cur, entitySqlDaoWrapperFactory, isBusEvent, 0, catalog, context);
}
@@ -633,7 +633,7 @@ public class DefaultSubscriptionDao extends EntityDaoBase<SubscriptionBundleMode
final UUID subscriptionId = subscription.getId();
Set<SubscriptionEventModelDao> targetEvents = new HashSet<SubscriptionEventModelDao>();
- final Date now = clock.getUTCNow().toDate();
+ final Date now = context.getCreatedDate().toDate();
final List<SubscriptionEventModelDao> eventModels = transactional.getFutureActiveEventForSubscription(subscriptionId.toString(), now, contextWithUpdatedDate);
for (final SubscriptionEventModelDao cur : eventModels) {
@@ -719,7 +719,7 @@ public class DefaultSubscriptionDao extends EntityDaoBase<SubscriptionBundleMode
for (final SubscriptionBaseEvent cur : inputChangeEvents) {
createAndRefresh(transactional, new SubscriptionEventModelDao(cur), context);
- final boolean isBusEvent = cur.getEffectiveDate().compareTo(clock.getUTCNow()) <= 0 && (cur.getType() == EventType.API_USER);
+ final boolean isBusEvent = cur.getEffectiveDate().compareTo(context.getCreatedDate()) <= 0 && (cur.getType() == EventType.API_USER);
recordBusOrFutureNotificationFromTransaction(subscription, cur, entitySqlDaoWrapperFactory, isBusEvent, 0, catalog, context);
}
@@ -772,7 +772,7 @@ public class DefaultSubscriptionDao extends EntityDaoBase<SubscriptionBundleMode
final SubscriptionEventModelDao cancelEventWithUpdatedTotalOrdering = createAndRefresh(subscriptionEventSqlDao, new SubscriptionEventModelDao(cancelEvent), context);
final SubscriptionBaseEvent refreshedSubscriptionEvent = SubscriptionEventModelDao.toSubscriptionEvent(cancelEventWithUpdatedTotalOrdering);
- final boolean isBusEvent = refreshedSubscriptionEvent.getEffectiveDate().compareTo(clock.getUTCNow()) <= 0;
+ final boolean isBusEvent = refreshedSubscriptionEvent.getEffectiveDate().compareTo(context.getCreatedDate()) <= 0;
recordBusOrFutureNotificationFromTransaction(subscription, refreshedSubscriptionEvent, entitySqlDaoWrapperFactory, isBusEvent, seqId, catalog, context);
// Notify the Bus of the requested change
@@ -811,7 +811,7 @@ public class DefaultSubscriptionDao extends EntityDaoBase<SubscriptionBundleMode
@Nullable final ApiEventType apiType, final InternalCallContext context) {
SubscriptionEventModelDao futureEvent = null;
- final Date now = clock.getUTCNow().toDate();
+ final Date now = context.getCreatedDate().toDate();
final List<SubscriptionEventModelDao> eventModels = dao.become(SubscriptionEventSqlDao.class).getFutureActiveEventForSubscription(subscriptionId.toString(), now, context);
for (final SubscriptionEventModelDao cur : eventModels) {
@@ -923,7 +923,6 @@ public class DefaultSubscriptionDao extends EntityDaoBase<SubscriptionBundleMode
}
if (baseTriggerEventForAddOnCancellation != null) {
- final DateTime now = clock.getUTCNow();
final SubscriptionBaseEvent addOnCancelEvent = new ApiEventCancel(new ApiEventBuilder()
.setSubscriptionId(reloaded.getId())
.setEffectiveDate(baseTriggerEventForAddOnCancellation.getEffectiveDate())
@@ -1043,7 +1042,7 @@ public class DefaultSubscriptionDao extends EntityDaoBase<SubscriptionBundleMode
// Notify the Bus
notifyBusOfRequestedChange(entitySqlDaoWrapperFactory, subscription, bcdEvent, SubscriptionBaseTransitionType.BCD_CHANGE, context);
- final boolean isBusEvent = bcdEvent.getEffectiveDate().compareTo(clock.getUTCNow()) <= 0;
+ final boolean isBusEvent = bcdEvent.getEffectiveDate().compareTo(context.getCreatedDate()) <= 0;
recordBusOrFutureNotificationFromTransaction(subscription, bcdEvent, entitySqlDaoWrapperFactory, isBusEvent, 0, catalog, context);
return null;
@@ -1186,7 +1185,7 @@ public class DefaultSubscriptionDao extends EntityDaoBase<SubscriptionBundleMode
}
private InternalCallContext contextWithUpdatedDate(final InternalCallContext input) {
- return new InternalCallContext(input, clock.getUTCNow());
+ return new InternalCallContext(input, input.getCreatedDate());
}
}
diff --git a/subscription/src/test/java/org/killbill/billing/subscription/api/transfer/TestTransfer.java b/subscription/src/test/java/org/killbill/billing/subscription/api/transfer/TestTransfer.java
index b9a0c21..7f3dc38 100644
--- a/subscription/src/test/java/org/killbill/billing/subscription/api/transfer/TestTransfer.java
+++ b/subscription/src/test/java/org/killbill/billing/subscription/api/transfer/TestTransfer.java
@@ -305,7 +305,7 @@ public class TestTransfer extends SubscriptionTestSuiteWithEmbeddedDB {
clock.addDays(3);
final String aoProduct1 = "Telescopic-Scope";
final BillingPeriod aoTerm1 = BillingPeriod.MONTHLY;
- final DefaultSubscriptionBase aoSubscription1 = testUtil.createSubscription(bundle, baseSubscription, aoProduct1, aoTerm1, basePriceList);
+ final DefaultSubscriptionBase aoSubscription1 = testUtil.createSubscription(bundle, aoProduct1, aoTerm1, basePriceList);
assertEquals(aoSubscription1.getState(), EntitlementState.ACTIVE);
// MOVE ANOTHER 25 DAYS AND CREATE AO2 [ BP STILL IN TRIAL]
@@ -313,7 +313,7 @@ public class TestTransfer extends SubscriptionTestSuiteWithEmbeddedDB {
clock.addDays(25);
final String aoProduct2 = "Laser-Scope";
final BillingPeriod aoTerm2 = BillingPeriod.MONTHLY;
- final DefaultSubscriptionBase aoSubscription2 = testUtil.createSubscription(bundle, baseSubscription, aoProduct2, aoTerm2, basePriceList);
+ final DefaultSubscriptionBase aoSubscription2 = testUtil.createSubscription(bundle, aoProduct2, aoTerm2, basePriceList);
assertEquals(aoSubscription2.getState(), EntitlementState.ACTIVE);
// MOVE AFTER TRIAL AND AO DISCOUNT PHASE [LASER SCOPE STILL IN DISCOUNT]
@@ -397,7 +397,7 @@ public class TestTransfer extends SubscriptionTestSuiteWithEmbeddedDB {
clock.addDays(3);
final String aoProduct1 = "Telescopic-Scope";
final BillingPeriod aoTerm1 = BillingPeriod.MONTHLY;
- final DefaultSubscriptionBase aoSubscription1 = testUtil.createSubscription(bundle, baseSubscription, aoProduct1, aoTerm1, basePriceList);
+ final DefaultSubscriptionBase aoSubscription1 = testUtil.createSubscription(bundle, aoProduct1, aoTerm1, basePriceList);
assertEquals(aoSubscription1.getState(), EntitlementState.ACTIVE);
testListener.pushExpectedEvent(NextEvent.PHASE);
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 87a882a..48f3c80 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
@@ -44,7 +44,6 @@ 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;
@@ -138,40 +137,27 @@ public class TestSubscriptionHelper {
};
}
- public DefaultSubscriptionBase createSubscription(final SubscriptionBaseBundle bundle, final String productName, final BillingPeriod term, final String planSet, final DateTime requestedDate)
+ public DefaultSubscriptionBase createSubscription(final SubscriptionBaseBundle bundle, final String productName, final BillingPeriod term, final String planSet, final LocalDate requestedDate)
throws SubscriptionBaseApiException {
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 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 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);
+ return createSubscription(bundle, productName, term, planSet, null, null);
}
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);
+ return createSubscription(noEvents, bundle, productName, term, planSet, null, null);
}
- public DefaultSubscriptionBase createSubscription(final SubscriptionBaseBundle bundle, final SubscriptionBase baseSubscription, final String productName, final BillingPeriod term, final String planSet, final PhaseType phaseType, final DateTime requestedDate)
+ public DefaultSubscriptionBase createSubscription(final SubscriptionBaseBundle bundle, final String productName, final BillingPeriod term, final String planSet, final PhaseType phaseType, final LocalDate requestedDate)
throws SubscriptionBaseApiException {
- return createSubscription(false, bundle, baseSubscription, productName, term, planSet, phaseType, requestedDate);
+ return createSubscription(false, bundle, 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 {
+ private DefaultSubscriptionBase createSubscription(final boolean noEvents, @Nullable final SubscriptionBaseBundle bundle, final String productName, final BillingPeriod term, final String planSet, final PhaseType phaseType, final LocalDate requestedDate)
+ throws SubscriptionBaseApiException {
// Make sure the right account information is used
final InternalCallContext internalCallContext = bundle == null ? this.internalCallContext : internalCallContextFactory.createInternalCallContext(bundle.getAccountId(),
ObjectType.ACCOUNT,
@@ -189,7 +175,7 @@ public class TestSubscriptionHelper {
}
}
- if (!noEvents && (requestedDate == null || requestedDate.compareTo(clock.getUTCNow()) <= 0)) {
+ if (!noEvents && (requestedDate == null || requestedDate.compareTo(clock.getUTCToday()) <= 0)) {
testListener.pushExpectedEvent(NextEvent.CREATE);
}
diff --git a/subscription/src/test/java/org/killbill/billing/subscription/api/user/TestUserApiAddOn.java b/subscription/src/test/java/org/killbill/billing/subscription/api/user/TestUserApiAddOn.java
index cfa1bde..4503630 100644
--- a/subscription/src/test/java/org/killbill/billing/subscription/api/user/TestUserApiAddOn.java
+++ b/subscription/src/test/java/org/killbill/billing/subscription/api/user/TestUserApiAddOn.java
@@ -59,7 +59,7 @@ public class TestUserApiAddOn extends SubscriptionTestSuiteWithEmbeddedDB {
final BillingPeriod aoTerm = BillingPeriod.MONTHLY;
final String aoPriceList = PriceListSet.DEFAULT_PRICELIST_NAME;
- DefaultSubscriptionBase aoSubscription = testUtil.createSubscription(bundle, baseSubscription, aoProduct, aoTerm, aoPriceList);
+ DefaultSubscriptionBase aoSubscription = testUtil.createSubscription(bundle, aoProduct, aoTerm, aoPriceList);
assertEquals(aoSubscription.getState(), EntitlementState.ACTIVE);
testListener.pushExpectedEvent(NextEvent.CANCEL);
@@ -85,7 +85,7 @@ public class TestUserApiAddOn extends SubscriptionTestSuiteWithEmbeddedDB {
final BillingPeriod aoTerm = BillingPeriod.MONTHLY;
final String aoPriceList = PriceListSet.DEFAULT_PRICELIST_NAME;
- DefaultSubscriptionBase aoSubscription = testUtil.createSubscription(bundle, baseSubscription, aoProduct, aoTerm, aoPriceList);
+ DefaultSubscriptionBase aoSubscription = testUtil.createSubscription(bundle, aoProduct, aoTerm, aoPriceList);
assertEquals(aoSubscription.getState(), EntitlementState.ACTIVE);
// Move clock after a month
@@ -159,7 +159,7 @@ public class TestUserApiAddOn extends SubscriptionTestSuiteWithEmbeddedDB {
final BillingPeriod aoTerm = BillingPeriod.MONTHLY;
final String aoPriceList = PriceListSet.DEFAULT_PRICELIST_NAME;
- DefaultSubscriptionBase aoSubscription = testUtil.createSubscription(bundle, baseSubscription, aoProduct, aoTerm, aoPriceList);
+ DefaultSubscriptionBase aoSubscription = testUtil.createSubscription(bundle, aoProduct, aoTerm, aoPriceList);
testListener.pushExpectedEvent(NextEvent.PHASE);
testListener.pushExpectedEvent(NextEvent.PHASE);
@@ -213,7 +213,7 @@ public class TestUserApiAddOn extends SubscriptionTestSuiteWithEmbeddedDB {
final BillingPeriod aoTerm = BillingPeriod.MONTHLY;
final String aoPriceList = PriceListSet.DEFAULT_PRICELIST_NAME;
- DefaultSubscriptionBase aoSubscription = testUtil.createSubscription(bundle, baseSubscription, aoProduct, aoTerm, aoPriceList);
+ DefaultSubscriptionBase aoSubscription = testUtil.createSubscription(bundle, aoProduct, aoTerm, aoPriceList);
testListener.pushExpectedEvent(NextEvent.PHASE);
testListener.pushExpectedEvent(NextEvent.PHASE);
@@ -277,7 +277,7 @@ public class TestUserApiAddOn extends SubscriptionTestSuiteWithEmbeddedDB {
final BillingPeriod aoTerm = BillingPeriod.MONTHLY;
final String aoPriceList = PriceListSet.DEFAULT_PRICELIST_NAME;
- DefaultSubscriptionBase aoSubscription = testUtil.createSubscription(bundle, baseSubscription, aoProduct, aoTerm, aoPriceList);
+ DefaultSubscriptionBase aoSubscription = testUtil.createSubscription(bundle, aoProduct, aoTerm, aoPriceList);
testListener.pushExpectedEvent(NextEvent.PHASE);
testListener.pushExpectedEvent(NextEvent.PHASE);
@@ -335,7 +335,7 @@ public class TestUserApiAddOn extends SubscriptionTestSuiteWithEmbeddedDB {
final String aoPriceList = PriceListSet.DEFAULT_PRICELIST_NAME;
// CREATE AO
- DefaultSubscriptionBase aoSubscription = testUtil.createSubscription(bundle, baseSubscription, aoProduct, aoTerm, aoPriceList);
+ DefaultSubscriptionBase aoSubscription = testUtil.createSubscription(bundle, aoProduct, aoTerm, aoPriceList);
testListener.pushExpectedEvent(NextEvent.PHASE);
testListener.pushExpectedEvent(NextEvent.PHASE);
@@ -434,7 +434,7 @@ public class TestUserApiAddOn extends SubscriptionTestSuiteWithEmbeddedDB {
// CREATE ADDON
final DateTime beforeAOCreation = clock.getUTCNow();
- DefaultSubscriptionBase aoSubscription = testUtil.createSubscription(bundle, baseSubscription, aoProduct, aoTerm, aoPriceList);
+ DefaultSubscriptionBase aoSubscription = testUtil.createSubscription(bundle, aoProduct, aoTerm, aoPriceList);
final DateTime afterAOCreation = clock.getUTCNow();
// CHECK EVERYTHING
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 63114db..b32981b 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
@@ -24,7 +24,6 @@ import org.joda.time.DateTime;
import org.joda.time.Interval;
import org.joda.time.LocalDate;
import org.killbill.billing.ErrorCode;
-import org.killbill.billing.api.FlakyRetryAnalyzer;
import org.killbill.billing.api.TestApiListener.NextEvent;
import org.killbill.billing.catalog.api.BillingActionPolicy;
import org.killbill.billing.catalog.api.BillingPeriod;
@@ -394,13 +393,13 @@ public class TestUserApiCancel extends SubscriptionTestSuiteWithEmbeddedDB {
@Test(groups = "slow")
public void testCancelUncancelFutureSubscription() throws SubscriptionBaseApiException {
- final DateTime init = clock.getUTCNow();
+ final LocalDate init = clock.getUTCToday();
final String productName = "Shotgun";
final BillingPeriod term = BillingPeriod.MONTHLY;
final String planSetName = PriceListSet.DEFAULT_PRICELIST_NAME;
- final DateTime futureCreationDate = init.plusDays(10);
+ final LocalDate futureCreationDate = init.plusDays(10);
DefaultSubscriptionBase subscription = testUtil.createSubscription(bundle, productName, term, planSetName, futureCreationDate);
assertListenerStatus();
@@ -441,11 +440,11 @@ public class TestUserApiCancel extends SubscriptionTestSuiteWithEmbeddedDB {
final BillingPeriod baseTerm = BillingPeriod.MONTHLY;
final String basePriceList = PriceListSet.DEFAULT_PRICELIST_NAME;
- final DateTime startDate = clock.getUTCNow().plusDays(5);
+ final LocalDate startDate = clock.getUTCToday().plusDays(5);
final DefaultSubscriptionBase subscription = testUtil.createSubscription(bundle, baseProduct, baseTerm, basePriceList, startDate);
assertEquals(subscription.getState(), Entitlement.EntitlementState.PENDING);
- assertEquals(subscription.getStartDate().compareTo(startDate), 0);
+ assertEquals(subscription.getStartDate().compareTo(startDate.toDateTime(accountData.getReferenceTime())), 0);
// The code will be smart to infer the cancelation date as being the future startDate
subscription.cancel(callContext);
@@ -455,7 +454,7 @@ public class TestUserApiCancel extends SubscriptionTestSuiteWithEmbeddedDB {
assertListenerStatus();
final DefaultSubscriptionBase subscription2 = (DefaultSubscriptionBase) subscriptionInternalApi.getSubscriptionFromId(subscription.getId(), internalCallContext);
- assertEquals(subscription2.getStartDate().compareTo(startDate), 0);
+ assertEquals(subscription2.getStartDate().compareTo(subscription.getStartDate()), 0);
assertEquals(subscription2.getState(), Entitlement.EntitlementState.CANCELLED);
assertNull(subscription2.getCurrentPlan());
}
@@ -467,11 +466,11 @@ public class TestUserApiCancel extends SubscriptionTestSuiteWithEmbeddedDB {
final BillingPeriod baseTerm = BillingPeriod.MONTHLY;
final String basePriceList = PriceListSet.DEFAULT_PRICELIST_NAME;
- final DateTime startDate = clock.getUTCNow().plusDays(5);
+ final LocalDate startDate = clock.getUTCToday().plusDays(5);
final DefaultSubscriptionBase subscription = testUtil.createSubscription(bundle, baseProduct, baseTerm, basePriceList, startDate);
assertEquals(subscription.getState(), Entitlement.EntitlementState.PENDING);
- assertEquals(subscription.getStartDate().compareTo(startDate), 0);
+ assertEquals(subscription.getStartDate().compareTo(startDate.toDateTime(accountData.getReferenceTime())), 0);
try {
subscription.cancelWithDate(null, callContext);
@@ -481,20 +480,20 @@ public class TestUserApiCancel extends SubscriptionTestSuiteWithEmbeddedDB {
}
try {
- subscription.cancelWithDate(startDate.minusDays(1), callContext);
+ subscription.cancelWithDate(subscription.getStartDate().minusDays(1), callContext);
fail("Cancel plan should have failed : subscription PENDING");
} catch (SubscriptionBaseApiException e) {
assertEquals(e.getCode(), ErrorCode.SUB_INVALID_REQUESTED_DATE.getCode());
}
- subscription.cancelWithDate(startDate, callContext);
+ subscription.cancelWithDate(subscription.getStartDate(), callContext);
testListener.pushExpectedEvents(NextEvent.CREATE, NextEvent.CANCEL);
clock.addDays(5);
assertListenerStatus();
final DefaultSubscriptionBase subscription2 = (DefaultSubscriptionBase) subscriptionInternalApi.getSubscriptionFromId(subscription.getId(), internalCallContext);
- assertEquals(subscription2.getStartDate().compareTo(startDate), 0);
+ assertEquals(subscription2.getStartDate().compareTo(subscription.getStartDate()), 0);
assertEquals(subscription2.getState(), Entitlement.EntitlementState.CANCELLED);
assertNull(subscription2.getCurrentPlan());
}
@@ -507,11 +506,11 @@ public class TestUserApiCancel extends SubscriptionTestSuiteWithEmbeddedDB {
final BillingPeriod baseTerm = BillingPeriod.MONTHLY;
final String basePriceList = PriceListSet.DEFAULT_PRICELIST_NAME;
- final DateTime startDate = clock.getUTCNow().plusDays(5);
+ final LocalDate startDate = clock.getUTCToday().plusDays(5);
final DefaultSubscriptionBase subscription = testUtil.createSubscription(bundle, baseProduct, baseTerm, basePriceList, startDate);
assertEquals(subscription.getState(), Entitlement.EntitlementState.PENDING);
- assertEquals(subscription.getStartDate().compareTo(startDate), 0);
+ assertEquals(subscription.getStartDate().compareTo(startDate.toDateTime(accountData.getReferenceTime())), 0);
subscription.cancelWithPolicy(BillingActionPolicy.IMMEDIATE, 1, callContext);
@@ -520,7 +519,7 @@ public class TestUserApiCancel extends SubscriptionTestSuiteWithEmbeddedDB {
assertListenerStatus();
final DefaultSubscriptionBase subscription2 = (DefaultSubscriptionBase) subscriptionInternalApi.getSubscriptionFromId(subscription.getId(), internalCallContext);
- assertEquals(subscription2.getStartDate().compareTo(startDate), 0);
+ assertEquals(subscription2.getStartDate().compareTo(subscription.getStartDate()), 0);
assertEquals(subscription2.getState(), Entitlement.EntitlementState.CANCELLED);
assertNull(subscription2.getCurrentPlan());
}
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 9b83b81..04e31de 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
@@ -467,7 +467,7 @@ public class TestUserApiChangePlan extends SubscriptionTestSuiteWithEmbeddedDB {
final String aoProduct = "Laser-Scope";
final BillingPeriod aoTerm = BillingPeriod.MONTHLY;
final String aoPriceList = PriceListSet.DEFAULT_PRICELIST_NAME;
- DefaultSubscriptionBase aoSubscription = testUtil.createSubscription(bundle, baseSubscription, aoProduct, aoTerm, aoPriceList);
+ DefaultSubscriptionBase aoSubscription = testUtil.createSubscription(bundle, aoProduct, aoTerm, aoPriceList);
try {
aoSubscription.changePlanWithDate(new PlanPhaseSpecifier(baseProduct, baseTerm, basePriceList), null, clock.getUTCNow(), callContext);
@@ -484,11 +484,11 @@ public class TestUserApiChangePlan extends SubscriptionTestSuiteWithEmbeddedDB {
final BillingPeriod baseTerm = BillingPeriod.MONTHLY;
final String basePriceList = PriceListSet.DEFAULT_PRICELIST_NAME;
- final DateTime startDate = clock.getUTCNow().plusDays(5);
+ final LocalDate startDate = clock.getUTCToday().plusDays(5);
final DefaultSubscriptionBase subscription = testUtil.createSubscription(bundle, baseProduct, baseTerm, basePriceList, startDate);
assertEquals(subscription.getState(), Entitlement.EntitlementState.PENDING);
- assertEquals(subscription.getStartDate().compareTo(startDate), 0);
+ assertEquals(subscription.getStartDate().compareTo(startDate.toDateTime(accountData.getReferenceTime())), 0);
final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Pistol", baseTerm, basePriceList, null);
@@ -502,21 +502,21 @@ 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);
+ final DryRunArguments dryRunArguments2 = testUtil.createDryRunArguments(subscription.getId(), subscription.getBundleId(), spec, startDate.minusDays(1), SubscriptionEventType.CHANGE, null);
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());
}
try {
- subscription.changePlanWithDate(spec, null, startDate.minusDays(1), callContext);
+ subscription.changePlanWithDate(spec, null, subscription.getStartDate().minusDays(1), callContext);
fail("Change plan should have failed : subscription PENDING");
} catch (final SubscriptionBaseApiException e) {
assertEquals(e.getCode(), ErrorCode.SUB_INVALID_REQUESTED_DATE.getCode());
}
// 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 DryRunArguments dryRunArguments3 = testUtil.createDryRunArguments(subscription.getId(), subscription.getBundleId(), spec, startDate, SubscriptionEventType.CHANGE, null);
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");
@@ -540,7 +540,7 @@ public class TestUserApiChangePlan extends SubscriptionTestSuiteWithEmbeddedDB {
final DefaultSubscriptionBase refreshed1 = (DefaultSubscriptionBase) subscriptionInternalApi.getSubscriptionFromId(subscription.getId(), internalCallContext);
assertEquals(refreshed1.getEvents().size(), subscription.getEvents().size() + 1);
- subscription.changePlanWithDate(spec, null, startDate, callContext);
+ subscription.changePlanWithDate(spec, null, subscription.getStartDate(), callContext);
assertListenerStatus();
// Move clock to startDate
@@ -549,7 +549,7 @@ public class TestUserApiChangePlan extends SubscriptionTestSuiteWithEmbeddedDB {
assertListenerStatus();
final DefaultSubscriptionBase subscription2 = (DefaultSubscriptionBase) subscriptionInternalApi.getSubscriptionFromId(subscription.getId(), internalCallContext);
- assertEquals(subscription2.getStartDate().compareTo(startDate), 0);
+ assertEquals(subscription2.getStartDate().compareTo(subscription.getStartDate()), 0);
assertEquals(subscription2.getState(), Entitlement.EntitlementState.ACTIVE);
assertEquals(subscription2.getCurrentPlan().getProduct().getName(), "Pistol");
// Same original # active events
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 1cdba9a..d659598 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
@@ -24,6 +24,7 @@ import java.util.List;
import org.joda.time.DateTime;
import org.joda.time.Interval;
+import org.joda.time.LocalDate;
import org.killbill.billing.ErrorCode;
import org.killbill.billing.api.TestApiListener.NextEvent;
import org.killbill.billing.catalog.api.BillingPeriod;
@@ -55,8 +56,8 @@ public class TestUserApiCreate extends SubscriptionTestSuiteWithEmbeddedDB {
@Test(groups = "slow")
public void testCreateBundlesWithSameExternalKeys() throws SubscriptionBaseApiException {
- final DateTime init = clock.getUTCNow();
- final DateTime requestedDate = init.minusYears(1);
+ final LocalDate init = clock.getUTCToday();
+ final LocalDate requestedDate = init.minusYears(1);
final String productName = "Shotgun";
final BillingPeriod term = BillingPeriod.MONTHLY;
@@ -67,7 +68,6 @@ public class TestUserApiCreate extends SubscriptionTestSuiteWithEmbeddedDB {
assertListenerStatus();
assertNotNull(subscription);
-
// Verify we can't create a second bundle with the same key
try {
subscriptionInternalApi.createBundleForAccount(bundle.getAccountId(), DefaultSubscriptionTestInitializer.DEFAULT_BUNDLE_KEY, true, internalCallContext);
@@ -100,8 +100,8 @@ public class TestUserApiCreate extends SubscriptionTestSuiteWithEmbeddedDB {
@Test(groups = "slow")
public void testCreateWithRequestedDate() throws SubscriptionBaseApiException {
- final DateTime init = clock.getUTCNow();
- final DateTime requestedDate = init.minusYears(1);
+ final LocalDate init = clock.getUTCToday();
+ final LocalDate requestedDate = init.minusYears(1);
final String productName = "Shotgun";
final BillingPeriod term = BillingPeriod.MONTHLY;
@@ -122,7 +122,7 @@ public class TestUserApiCreate extends SubscriptionTestSuiteWithEmbeddedDB {
final SubscriptionBaseEvent phaseEvent = events.get(1);
assertEquals(subscription.getBundleExternalKey(), bundle.getExternalKey());
- assertEquals(subscription.getStartDate(), requestedDate);
+ assertEquals(subscription.getStartDate(), requestedDate.toDateTime(accountData.getReferenceTime()));
assertListenerStatus();
@@ -143,7 +143,7 @@ public class TestUserApiCreate extends SubscriptionTestSuiteWithEmbeddedDB {
final BillingPeriod term = BillingPeriod.MONTHLY;
final String planSetName = PriceListSet.DEFAULT_PRICELIST_NAME;
- final DefaultSubscriptionBase subscription = testUtil.createSubscription(bundle, productName, term, planSetName, PhaseType.EVERGREEN, clock.getUTCNow());
+ final DefaultSubscriptionBase subscription = testUtil.createSubscription(bundle, productName, term, planSetName, PhaseType.EVERGREEN, null);
assertNotNull(subscription);
assertEquals(subscription.getBundleExternalKey(), bundle.getExternalKey());
@@ -171,7 +171,7 @@ public class TestUserApiCreate extends SubscriptionTestSuiteWithEmbeddedDB {
final BillingPeriod term = BillingPeriod.MONTHLY;
final String planSetName = PriceListSet.DEFAULT_PRICELIST_NAME;
- final DefaultSubscriptionBase subscription = testUtil.createSubscription(bundle, productName, term, planSetName, clock.getUTCNow());
+ final DefaultSubscriptionBase subscription = testUtil.createSubscription(bundle, productName, term, planSetName);
assertNotNull(subscription);
assertEquals(subscription.getBundleExternalKey(), bundle.getExternalKey());
@@ -215,7 +215,7 @@ public class TestUserApiCreate extends SubscriptionTestSuiteWithEmbeddedDB {
final String planSetName = "gunclubDiscount";
// CREATE SUBSCRIPTION
- DefaultSubscriptionBase subscription = testUtil.createSubscription(bundle, productName, term, planSetName, clock.getUTCNow());
+ DefaultSubscriptionBase subscription = testUtil.createSubscription(bundle, productName, term, planSetName);
assertNotNull(subscription);
PlanPhase currentPhase = subscription.getCurrentPhase();
@@ -252,22 +252,21 @@ public class TestUserApiCreate extends SubscriptionTestSuiteWithEmbeddedDB {
final BillingPeriod term = BillingPeriod.ANNUAL;
final String planSetName = PriceListSet.DEFAULT_PRICELIST_NAME;
- final DefaultSubscriptionBase subscription = testUtil.createSubscription(bundle, productName, term, planSetName, clock.getUTCNow());
+ final DefaultSubscriptionBase subscription = testUtil.createSubscription(bundle, productName, term, planSetName);
assertNotNull(subscription);
assertListenerStatus();
}
-
@Test(groups = "slow")
public void testCreateSubscriptionInTheFuture() throws SubscriptionBaseApiException {
- final DateTime init = clock.getUTCNow();
+ final LocalDate init = clock.getUTCToday();
final String productName = "Shotgun";
final BillingPeriod term = BillingPeriod.MONTHLY;
final String planSetName = PriceListSet.DEFAULT_PRICELIST_NAME;
- final DateTime futureCreationDate = init.plusDays(10);
+ final LocalDate futureCreationDate = init.plusDays(10);
DefaultSubscriptionBase subscription = testUtil.createSubscription(bundle, productName, term, planSetName, futureCreationDate);
assertListenerStatus();
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 3393722..4f0a717 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
@@ -23,7 +23,6 @@ import javax.annotation.Nullable;
import org.joda.time.DateTime;
import org.joda.time.Interval;
import org.killbill.billing.ErrorCode;
-import org.killbill.billing.api.FlakyRetryAnalyzer;
import org.killbill.billing.api.TestApiListener.NextEvent;
import org.killbill.billing.catalog.api.BillingActionPolicy;
import org.killbill.billing.catalog.api.BillingPeriod;
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 5daabf1..255a4d1 100644
--- a/subscription/src/test/java/org/killbill/billing/subscription/SubscriptionTestSuiteNoDB.java
+++ b/subscription/src/test/java/org/killbill/billing/subscription/SubscriptionTestSuiteNoDB.java
@@ -91,8 +91,7 @@ public class SubscriptionTestSuiteNoDB extends GuicyKillbillTestSuiteNoDB {
protected SubscriptionConfig config;
@Inject
protected SubscriptionDao dao;
- @Inject
- protected ClockMock clock;
+
@Inject
protected BusService busService;
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 fb54d56..4f443c0 100644
--- a/subscription/src/test/java/org/killbill/billing/subscription/SubscriptionTestSuiteWithEmbeddedDB.java
+++ b/subscription/src/test/java/org/killbill/billing/subscription/SubscriptionTestSuiteWithEmbeddedDB.java
@@ -81,8 +81,6 @@ public class SubscriptionTestSuiteWithEmbeddedDB extends GuicyKillbillTestSuiteW
@Inject
protected SubscriptionDao dao;
@Inject
- protected ClockMock clock;
- @Inject
protected BusService busService;
@Inject
protected AddonUtils addonUtils;
diff --git a/util/src/main/java/org/killbill/billing/util/callcontext/InternalCallContextFactory.java b/util/src/main/java/org/killbill/billing/util/callcontext/InternalCallContextFactory.java
index 41158ff..ec78672 100644
--- a/util/src/main/java/org/killbill/billing/util/callcontext/InternalCallContextFactory.java
+++ b/util/src/main/java/org/killbill/billing/util/callcontext/InternalCallContextFactory.java
@@ -247,7 +247,7 @@ public class InternalCallContextFactory {
// If tenant id is null, this will default to the default tenant record id (multi-tenancy disabled)
final Long tenantRecordId = getTenantRecordIdSafe(context);
populateMDCContext(context.getUserToken(), null, tenantRecordId);
- return new InternalCallContext(tenantRecordId, context, clock.getUTCNow());
+ return new InternalCallContext(tenantRecordId, context, context.getCreatedDate());
}
// Used when we need to re-hydrate the callcontext with the account_record_id (when creating the account)
@@ -256,7 +256,7 @@ public class InternalCallContextFactory {
final DateTimeZone fixedOffsetTimeZone = immutableAccountData.getFixedOffsetTimeZone();
final DateTime referenceTime = immutableAccountData.getReferenceTime();
populateMDCContext(context.getUserToken(), accountRecordId, context.getTenantRecordId());
- return new InternalCallContext(context, accountRecordId, fixedOffsetTimeZone, referenceTime, clock.getUTCNow());
+ return new InternalCallContext(context, accountRecordId, fixedOffsetTimeZone, referenceTime, context.getCreatedDate());
}
// Used during the account creation transaction (account not visible outside of the transaction yet)
@@ -265,12 +265,12 @@ public class InternalCallContextFactory {
final DateTimeZone fixedOffsetTimeZone = AccountDateTimeUtils.getFixedOffsetTimeZone(accountModelDao);
final DateTime referenceTime = accountModelDao.getReferenceTime();
populateMDCContext(context.getUserToken(), accountRecordId, context.getTenantRecordId());
- return new InternalCallContext(context, accountRecordId, fixedOffsetTimeZone, referenceTime, clock.getUTCNow());
+ return new InternalCallContext(context, accountRecordId, fixedOffsetTimeZone, referenceTime, context.getCreatedDate());
}
public InternalCallContext createInternalCallContext(final DateTimeZone fixedOffsetTimeZone, final DateTime referenceTime, final Long accountRecordId, final InternalCallContext context) {
populateMDCContext(context.getUserToken(), accountRecordId, context.getTenantRecordId());
- return new InternalCallContext(context, accountRecordId, fixedOffsetTimeZone, referenceTime, clock.getUTCNow());
+ return new InternalCallContext(context, accountRecordId, fixedOffsetTimeZone, referenceTime, context.getCreatedDate());
}
private InternalCallContext createInternalCallContext(final UUID objectId, final ObjectType objectType, final String userName,
diff --git a/util/src/main/java/org/killbill/billing/util/entity/dao/EntitySqlDaoTransactionalJdbiWrapper.java b/util/src/main/java/org/killbill/billing/util/entity/dao/EntitySqlDaoTransactionalJdbiWrapper.java
index cb6c90e..a651330 100644
--- a/util/src/main/java/org/killbill/billing/util/entity/dao/EntitySqlDaoTransactionalJdbiWrapper.java
+++ b/util/src/main/java/org/killbill/billing/util/entity/dao/EntitySqlDaoTransactionalJdbiWrapper.java
@@ -37,7 +37,7 @@ import org.slf4j.LoggerFactory;
*/
public class EntitySqlDaoTransactionalJdbiWrapper {
- private final Logger logger = LoggerFactory.getLogger(EntitySqlDaoTransactionalJdbiWrapper.class);
+ private static final Logger logger = LoggerFactory.getLogger(EntitySqlDaoTransactionalJdbiWrapper.class);
private final DBRouterUntyped dbRouter;
private final Clock clock;
diff --git a/util/src/main/java/org/killbill/billing/util/entity/dao/EntitySqlDaoWrapperInvocationHandler.java b/util/src/main/java/org/killbill/billing/util/entity/dao/EntitySqlDaoWrapperInvocationHandler.java
index e5db8e3..195d41d 100644
--- a/util/src/main/java/org/killbill/billing/util/entity/dao/EntitySqlDaoWrapperInvocationHandler.java
+++ b/util/src/main/java/org/killbill/billing/util/entity/dao/EntitySqlDaoWrapperInvocationHandler.java
@@ -504,7 +504,7 @@ public class EntitySqlDaoWrapperInvocationHandler<S extends EntitySqlDao<M, E>,
}
private Long insertHistory(final Long entityRecordId, final M entityModelDao, final ChangeType changeType, final InternalCallContext context) {
- final EntityHistoryModelDao<M, E> history = new EntityHistoryModelDao<M, E>(entityModelDao, entityRecordId, changeType, null, clock.getUTCNow());
+ final EntityHistoryModelDao<M, E> history = new EntityHistoryModelDao<M, E>(entityModelDao, entityRecordId, changeType, null, context.getCreatedDate());
final Long recordId = sqlDao.addHistoryFromTransaction(history, context);
printSQLWarnings();
return recordId;
@@ -512,7 +512,7 @@ public class EntitySqlDaoWrapperInvocationHandler<S extends EntitySqlDao<M, E>,
private void insertAudits(final TableName tableName, final M entityModelDao, final Long entityRecordId, final Long historyRecordId, final ChangeType changeType, final InternalCallContext contextMaybeWithoutAccountRecordId) {
final TableName destinationTableName = MoreObjects.firstNonNull(tableName.getHistoryTableName(), tableName);
- final EntityAudit audit = new EntityAudit(destinationTableName, historyRecordId, changeType, clock.getUTCNow());
+ final EntityAudit audit = new EntityAudit(destinationTableName, historyRecordId, changeType, contextMaybeWithoutAccountRecordId.getCreatedDate());
final InternalCallContext context;
// Populate the account record id when creating the account record
diff --git a/util/src/test/java/org/killbill/billing/api/AbortAfterFirstFailureListener.java b/util/src/test/java/org/killbill/billing/api/AbortAfterFirstFailureListener.java
index 69c1600..c8a8aab 100644
--- a/util/src/test/java/org/killbill/billing/api/AbortAfterFirstFailureListener.java
+++ b/util/src/test/java/org/killbill/billing/api/AbortAfterFirstFailureListener.java
@@ -50,9 +50,13 @@ public class AbortAfterFirstFailureListener implements IInvokedMethodListener {
}
if (testResult.getStatus() == ITestResult.FAILURE) {
- synchronized (this) {
- logger.warn("!!! Test failure, all other tests will be skipped: {} !!!", testResult);
- hasFailures = true;
+ // Don't skip other tests with the current test method is flaky
+ final boolean isFlakyTest = method.getTestMethod().getRetryAnalyzer() != null && method.getTestMethod().getRetryAnalyzer() instanceof FlakyRetryAnalyzer;
+ if (!isFlakyTest) {
+ synchronized (this) {
+ logger.warn("!!! Test failure, all other tests will be skipped: {} !!!", testResult);
+ hasFailures = true;
+ }
}
}
}
diff --git a/util/src/test/java/org/killbill/billing/callcontext/MutableCallContext.java b/util/src/test/java/org/killbill/billing/callcontext/MutableCallContext.java
new file mode 100644
index 0000000..725df20
--- /dev/null
+++ b/util/src/test/java/org/killbill/billing/callcontext/MutableCallContext.java
@@ -0,0 +1,90 @@
+/*
+ * 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.callcontext;
+
+import java.util.UUID;
+
+import org.joda.time.DateTime;
+import org.killbill.billing.util.callcontext.CallContext;
+import org.killbill.billing.util.callcontext.CallOrigin;
+import org.killbill.billing.util.callcontext.UserType;
+
+public class MutableCallContext implements CallContext {
+
+ private final CallContext delegate;
+ private DateTime createdDate;
+
+ public MutableCallContext(final MutableInternalCallContext internalCallContext) {
+ this.delegate = internalCallContext.toCallContext(null, null);
+ this.createdDate = delegate.getCreatedDate();
+ }
+
+ @Override
+ public UUID getUserToken() {
+ return delegate.getUserToken();
+ }
+
+ @Override
+ public String getUserName() {
+ return delegate.getUserName();
+ }
+
+ @Override
+ public CallOrigin getCallOrigin() {
+ return delegate.getCallOrigin();
+ }
+
+ @Override
+ public UserType getUserType() {
+ return delegate.getUserType();
+ }
+
+ @Override
+ public String getReasonCode() {
+ return delegate.getReasonCode();
+ }
+
+ @Override
+ public String getComments() {
+ return delegate.getComments();
+ }
+
+ @Override
+ public DateTime getCreatedDate() {
+ return createdDate;
+ }
+
+ public void setCreatedDate(final DateTime createdDate) {
+ this.createdDate = createdDate;
+ }
+
+ @Override
+ public DateTime getUpdatedDate() {
+ return delegate.getUpdatedDate();
+ }
+
+ @Override
+ public UUID getAccountId() {
+ return delegate.getAccountId();
+ }
+
+ @Override
+ public UUID getTenantId() {
+ return delegate.getTenantId();
+ }
+}
diff --git a/util/src/test/java/org/killbill/billing/GuicyKillbillTestModule.java b/util/src/test/java/org/killbill/billing/GuicyKillbillTestModule.java
index e253aac..49cb620 100644
--- a/util/src/test/java/org/killbill/billing/GuicyKillbillTestModule.java
+++ b/util/src/test/java/org/killbill/billing/GuicyKillbillTestModule.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
@@ -22,6 +22,7 @@ import java.util.UUID;
import org.joda.time.DateTimeZone;
import org.killbill.billing.callcontext.InternalCallContext;
+import org.killbill.billing.callcontext.MutableCallContext;
import org.killbill.billing.callcontext.MutableInternalCallContext;
import org.killbill.billing.platform.api.KillbillConfigSource;
import org.killbill.billing.util.callcontext.CallContext;
@@ -52,7 +53,7 @@ public class GuicyKillbillTestModule extends KillBillModule {
GuicyKillbillTestSuite.getClock().getUTCNow(),
GuicyKillbillTestSuite.getClock().getUTCNow());
- private final CallContext callContext = internalCallContext.toCallContext(null,null);
+ private final MutableCallContext callContext = new MutableCallContext(internalCallContext);
public GuicyKillbillTestModule(final KillbillConfigSource configSource) {
super(configSource);
@@ -65,5 +66,6 @@ public class GuicyKillbillTestModule extends KillBillModule {
bind(InternalCallContext.class).toInstance(internalCallContext);
bind(MutableInternalCallContext.class).toInstance(internalCallContext);
bind(CallContext.class).toInstance(callContext);
+ bind(MutableCallContext.class).toInstance(callContext);
}
}
diff --git a/util/src/test/java/org/killbill/billing/GuicyKillbillTestSuite.java b/util/src/test/java/org/killbill/billing/GuicyKillbillTestSuite.java
index 794b71b..9d48932 100644
--- a/util/src/test/java/org/killbill/billing/GuicyKillbillTestSuite.java
+++ b/util/src/test/java/org/killbill/billing/GuicyKillbillTestSuite.java
@@ -23,20 +23,26 @@ import java.util.UUID;
import javax.inject.Inject;
+import org.joda.time.DateTime;
+import org.joda.time.DateTimeZone;
import org.killbill.billing.api.AbortAfterFirstFailureListener;
import org.killbill.billing.api.FlakyInvokedMethodListener;
import org.killbill.billing.callcontext.InternalTenantContext;
+import org.killbill.billing.callcontext.MutableCallContext;
import org.killbill.billing.callcontext.MutableInternalCallContext;
import org.killbill.billing.platform.api.KillbillConfigSource;
import org.killbill.billing.platform.test.config.TestKillbillConfigSource;
-import org.killbill.billing.util.callcontext.CallContext;
import org.killbill.billing.util.callcontext.InternalCallContextFactory;
import org.killbill.billing.util.callcontext.TenantContext;
import org.killbill.clock.Clock;
import org.killbill.clock.ClockMock;
+import org.mockito.Mockito;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
import org.skife.config.ConfigSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.testng.Assert;
import org.testng.IHookCallBack;
import org.testng.IHookable;
import org.testng.ITestResult;
@@ -59,7 +65,10 @@ public class GuicyKillbillTestSuite implements IHookable {
// Use the simple name here to save screen real estate
protected static final Logger log = LoggerFactory.getLogger(KillbillTestSuite.class.getSimpleName());
- private boolean hasFailed = false;
+ private static final ClockMock theStaticClock = new ClockMock();
+
+ protected final KillbillConfigSource configSource;
+ protected final ConfigSource skifeConfigSource;
@Inject
protected InternalCallContextFactory internalCallContextFactory;
@@ -68,15 +77,15 @@ public class GuicyKillbillTestSuite implements IHookable {
protected MutableInternalCallContext internalCallContext;
@Inject
- protected CallContext callContext;
+ protected MutableCallContext callContext;
@Inject
- protected ClockMock clock;
+ private ClockMock theRealClock;
- private static final ClockMock theStaticClock = new ClockMock();
+ // Initialized to avoid NPE when skipping tests, but see below
+ protected ClockMock clock = new ClockMock();
- protected final KillbillConfigSource configSource;
- protected final ConfigSource skifeConfigSource;
+ private boolean hasFailed = false;
public GuicyKillbillTestSuite() {
this.configSource = getConfigSource();
@@ -88,6 +97,23 @@ public class GuicyKillbillTestSuite implements IHookable {
};
}
+ public static ClockMock getClock() {
+ return theStaticClock;
+ }
+
+ public static void refreshCallContext(final UUID accountId,
+ final Clock clock,
+ final InternalCallContextFactory internalCallContextFactory,
+ final TenantContext callContext,
+ final MutableInternalCallContext internalCallContext) {
+ final InternalTenantContext tmp = internalCallContextFactory.createInternalTenantContext(accountId, callContext);
+ internalCallContext.setAccountRecordId(tmp.getAccountRecordId());
+ internalCallContext.setFixedOffsetTimeZone(tmp.getFixedOffsetTimeZone());
+ internalCallContext.setReferenceTime(tmp.getReferenceLocalTime());
+ internalCallContext.setCreatedDate(clock.getUTCNow());
+ internalCallContext.setUpdatedDate(clock.getUTCNow());
+ }
+
protected KillbillConfigSource getConfigSource() {
try {
return new TestKillbillConfigSource(DBTestingHelper.class);
@@ -112,27 +138,15 @@ public class GuicyKillbillTestSuite implements IHookable {
}
}
- public static ClockMock getClock() {
- return theStaticClock;
- }
-
- public static void refreshCallContext(final UUID accountId,
- final Clock clock,
- final InternalCallContextFactory internalCallContextFactory,
- final TenantContext callContext,
- final MutableInternalCallContext internalCallContext) {
- final InternalTenantContext tmp = internalCallContextFactory.createInternalTenantContext(accountId, callContext);
- internalCallContext.setAccountRecordId(tmp.getAccountRecordId());
- internalCallContext.setFixedOffsetTimeZone(tmp.getFixedOffsetTimeZone());
- internalCallContext.setReferenceTime(tmp.getReferenceLocalTime());
- internalCallContext.setCreatedDate(clock.getUTCNow());
- internalCallContext.setUpdatedDate(clock.getUTCNow());
- }
-
protected void refreshCallContext(final UUID accountId) {
refreshCallContext(accountId, clock, internalCallContextFactory, callContext, internalCallContext);
}
+ // Refresh the createdDate
+ protected void refreshCallContext() {
+ refreshCallContext(callContext.getAccountId(), clock, internalCallContextFactory, callContext, internalCallContext);
+ }
+
@BeforeMethod(alwaysRun = true)
public void beforeMethodAlwaysRun(final Method method) throws Exception {
if (AbortAfterFirstFailureListener.hasFailures()) {
@@ -146,6 +160,40 @@ public class GuicyKillbillTestSuite implements IHookable {
if (internalCallContext != null) {
internalCallContext.reset();
}
+
+ if (theRealClock != null) {
+ clock = Mockito.spy(theRealClock);
+ final Answer answer = new Answer() {
+ @Override
+ public Object answer(final InvocationOnMock invocation) throws Throwable {
+ // Sync clock and theRealClock
+ final Object realAnswer = invocation.callRealMethod();
+ invocation.getMethod().invoke(theRealClock, invocation.getArguments());
+
+ // Update the contexts createdDate each time we move the clock
+ final DateTime utcNow = theRealClock.getUTCNow();
+ if (callContext != null) {
+ callContext.setCreatedDate(utcNow);
+ }
+ if (internalCallContext != null) {
+ internalCallContext.setCreatedDate(utcNow);
+ }
+
+ return realAnswer;
+ }
+ };
+ Mockito.doAnswer(answer).when(clock).getUTCNow();
+ Mockito.doAnswer(answer).when(clock).getNow(Mockito.any(DateTimeZone.class));
+ Mockito.doAnswer(answer).when(clock).getUTCToday();
+ Mockito.doAnswer(answer).when(clock).getToday(Mockito.any(DateTimeZone.class));
+ Mockito.doAnswer(answer).when(clock).addDays(Mockito.anyInt());
+ Mockito.doAnswer(answer).when(clock).addWeeks(Mockito.anyInt());
+ Mockito.doAnswer(answer).when(clock).addMonths(Mockito.anyInt());
+ Mockito.doAnswer(answer).when(clock).addYears(Mockito.anyInt());
+ Mockito.doAnswer(answer).when(clock).addDeltaFromReality(Mockito.anyLong());
+ Mockito.doAnswer(answer).when(clock).setTime(Mockito.any(DateTime.class));
+ Mockito.doAnswer(answer).when(clock).resetDeltaFromReality();
+ }
}
@AfterMethod(alwaysRun = true)
diff --git a/util/src/test/java/org/killbill/billing/KillbillTestSuite.java b/util/src/test/java/org/killbill/billing/KillbillTestSuite.java
index ebb0d5b..7b4bdf7 100644
--- a/util/src/test/java/org/killbill/billing/KillbillTestSuite.java
+++ b/util/src/test/java/org/killbill/billing/KillbillTestSuite.java
@@ -20,8 +20,6 @@ package org.killbill.billing;
import java.lang.reflect.Method;
-import org.killbill.clock.Clock;
-import org.killbill.clock.ClockMock;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.testng.ITestResult;
@@ -35,8 +33,6 @@ public class KillbillTestSuite {
private boolean hasFailed = false;
- protected Clock clock = new ClockMock();
-
@BeforeMethod(alwaysRun = true)
public void startTestSuite(final Method method) throws Exception {
log.info("***************************************************************************************************");
@@ -48,8 +44,8 @@ public class KillbillTestSuite {
public void endTestSuite(final Method method, final ITestResult result) throws Exception {
log.info("***************************************************************************************************");
log.info("*** Ending test {}:{} {} ({} s.)", new Object[]{method.getDeclaringClass().getName(), method.getName(),
- result.isSuccess() ? "SUCCESS" : "!!! FAILURE !!!",
- (result.getEndMillis() - result.getStartMillis()) / 1000});
+ result.isSuccess() ? "SUCCESS" : "!!! FAILURE !!!",
+ (result.getEndMillis() - result.getStartMillis()) / 1000});
log.info("***************************************************************************************************");
if (!hasFailed && !result.isSuccess()) {
hasFailed = true;
diff --git a/util/src/test/java/org/killbill/billing/util/audit/AuditLogsTestBase.java b/util/src/test/java/org/killbill/billing/util/audit/AuditLogsTestBase.java
index 1025bac..98517c2 100644
--- a/util/src/test/java/org/killbill/billing/util/audit/AuditLogsTestBase.java
+++ b/util/src/test/java/org/killbill/billing/util/audit/AuditLogsTestBase.java
@@ -19,9 +19,9 @@ package org.killbill.billing.util.audit;
import java.util.List;
import java.util.UUID;
-import org.mockito.Mockito;
-
+import org.joda.time.DateTime;
import org.killbill.billing.util.UtilTestSuiteNoDB;
+import org.mockito.Mockito;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
@@ -39,7 +39,8 @@ public abstract class AuditLogsTestBase extends UtilTestSuiteNoDB {
protected AuditLog createAuditLog() {
final AuditLog auditLog = Mockito.mock(AuditLog.class);
- Mockito.when(auditLog.getCreatedDate()).thenReturn(clock.getUTCNow());
+ final DateTime utcNow = clock.getUTCNow();
+ Mockito.when(auditLog.getCreatedDate()).thenReturn(utcNow);
Mockito.when(auditLog.getReasonCode()).thenReturn(UUID.randomUUID().toString());
Mockito.when(auditLog.getUserName()).thenReturn(UUID.randomUUID().toString());
Mockito.when(auditLog.getUserToken()).thenReturn(UUID.randomUUID().toString());