killbill-memoizeit
Changes
entitlement/src/main/java/org/killbill/billing/entitlement/api/DefaultEntitlementApi.java 45(+26 -19)
subscription/src/main/java/org/killbill/billing/subscription/api/SubscriptionBaseApiService.java 2(+1 -1)
subscription/src/main/java/org/killbill/billing/subscription/api/svcs/DefaultSubscriptionInternalApi.java 171(+75 -96)
subscription/src/main/java/org/killbill/billing/subscription/api/user/DefaultSubscriptionBaseApiService.java 73(+33 -40)
subscription/src/main/java/org/killbill/billing/subscription/engine/dao/DefaultSubscriptionDao.java 72(+33 -39)
subscription/src/main/java/org/killbill/billing/subscription/engine/dao/SubscriptionDao.java 3(+2 -1)
subscription/src/test/java/org/killbill/billing/subscription/engine/dao/MockSubscriptionDaoMemory.java 16(+6 -10)
util/src/main/resources/org/killbill/billing/util/migration/V20161105000000__session_id.sql 3(+3 -0)
Details
diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml
index 99aecde..dfffbd8 100644
--- a/.idea/inspectionProfiles/Project_Default.xml
+++ b/.idea/inspectionProfiles/Project_Default.xml
@@ -19,10 +19,10 @@
<option name="loggerClassName" value="org.apache.log4j.Logger,org.slf4j.LoggerFactory,org.apache.commons.logging.LogFactory,java.util.logging.Logger" />
<option name="loggerFactoryMethodName" value="getLogger,getLogger,getLog,getLogger" />
</inspection_tool>
- <inspection_tool class="MagicNumber" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="MissortedModifiers" enabled="true" level="WARNING" enabled_by_default="true">
<option name="m_requireAnnotationsFirst" value="true" />
</inspection_tool>
+ <inspection_tool class="RedundantTypeArguments" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SizeReplaceableByIsEmpty" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="TypeMayBeWeakened" enabled="true" level="WARNING" enabled_by_default="true">
<option name="useRighthandTypeAsWeakestTypeInAssignments" value="true" />
diff --git a/account/src/main/resources/org/killbill/billing/account/ddl.sql b/account/src/main/resources/org/killbill/billing/account/ddl.sql
index 295a88d..031e560 100644
--- a/account/src/main/resources/org/killbill/billing/account/ddl.sql
+++ b/account/src/main/resources/org/killbill/billing/account/ddl.sql
@@ -1,4 +1,4 @@
-/*! SET storage_engine=INNODB */;
+/*! SET default_storage_engine=INNODB */;
DROP TABLE IF EXISTS accounts;
CREATE TABLE accounts (
diff --git a/api/src/main/java/org/killbill/billing/subscription/api/SubscriptionBaseInternalApi.java b/api/src/main/java/org/killbill/billing/subscription/api/SubscriptionBaseInternalApi.java
index 8599350..617049b 100644
--- a/api/src/main/java/org/killbill/billing/subscription/api/SubscriptionBaseInternalApi.java
+++ b/api/src/main/java/org/killbill/billing/subscription/api/SubscriptionBaseInternalApi.java
@@ -44,7 +44,6 @@ import org.killbill.billing.util.entity.Pagination;
public interface SubscriptionBaseInternalApi {
-
public SubscriptionBase createSubscription(UUID bundleId, PlanPhaseSpecifier spec, List<PlanPhasePriceOverride> overrides, DateTime requestedDateWithMs,
final boolean isMigrated, InternalCallContext context) throws SubscriptionBaseApiException;
@@ -103,6 +102,4 @@ public interface SubscriptionBaseInternalApi {
public void updateBCD(final UUID subscriptionId, final int bcd, @Nullable final LocalDate effectiveFromDate, final InternalCallContext internalCallContext) throws SubscriptionBaseApiException;
public int getDefaultBillCycleDayLocal(final Map<UUID, Integer> bcdCache, final SubscriptionBase subscription, final SubscriptionBase baseSubscription, final PlanPhaseSpecifier planPhaseSpecifier, final DateTimeZone accountTimeZone, final int accountBillCycleDayLocal, final DateTime effectiveDate, final InternalTenantContext context) throws SubscriptionBaseApiException;
-
-
}
diff --git a/beatrix/src/main/resources/org/killbill/billing/beatrix/ddl.sql b/beatrix/src/main/resources/org/killbill/billing/beatrix/ddl.sql
index 6ce6e8e..96f32e8 100644
--- a/beatrix/src/main/resources/org/killbill/billing/beatrix/ddl.sql
+++ b/beatrix/src/main/resources/org/killbill/billing/beatrix/ddl.sql
@@ -1,4 +1,4 @@
-/*! SET storage_engine=INNODB */;
+/*! SET default_storage_engine=INNODB */;
DROP TABLE IF EXISTS bus_ext_events;
CREATE TABLE bus_ext_events (
diff --git a/catalog/src/main/resources/org/killbill/billing/catalog/ddl.sql b/catalog/src/main/resources/org/killbill/billing/catalog/ddl.sql
index cb443fb..fce5967 100644
--- a/catalog/src/main/resources/org/killbill/billing/catalog/ddl.sql
+++ b/catalog/src/main/resources/org/killbill/billing/catalog/ddl.sql
@@ -1,4 +1,4 @@
-/*! SET storage_engine=INNODB */;
+/*! SET default_storage_engine=INNODB */;
DROP TABLE IF EXISTS catalog_override_plan_definition;
CREATE TABLE catalog_override_plan_definition (
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 bd890dc..a84469f 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
@@ -92,7 +92,6 @@ public class DefaultEntitlementApi extends DefaultEntitlementApiBase implements
private final BlockingChecker checker;
private final BlockingStateDao blockingStateDao;
private final EntitlementDateHelper dateHelper;
- private final PersistentBus eventBus;
private final EventsStreamBuilder eventsStreamBuilder;
private final EntitlementUtils entitlementUtils;
private final NotificationQueueService notificationQueueService;
@@ -108,7 +107,6 @@ public class DefaultEntitlementApi extends DefaultEntitlementApiBase implements
final EntitlementPluginExecution pluginExecution,
final SecurityApi securityApi) {
super(eventBus, null, pluginExecution, internalCallContextFactory, subscriptionInternalApi, accountApi, blockingStateDao, clock, checker, notificationQueueService, eventsStreamBuilder, entitlementUtils, securityApi);
- this.eventBus = eventBus;
this.internalCallContextFactory = internalCallContextFactory;
this.subscriptionBaseInternalApi = subscriptionInternalApi;
this.subscriptionBaseTransferApi = subscriptionTransferApi;
@@ -125,7 +123,7 @@ public class DefaultEntitlementApi extends DefaultEntitlementApiBase implements
@Override
public Entitlement createBaseEntitlement(final UUID accountId, final PlanPhaseSpecifier planPhaseSpecifier, final String externalKey, final List<PlanPhasePriceOverride> overrides,
- @Nullable final LocalDate entitlementEffectiveDate, @Nullable LocalDate billingEffectiveDate, final boolean isMigrated,
+ @Nullable final LocalDate entitlementEffectiveDate, @Nullable final LocalDate billingEffectiveDate, final boolean isMigrated,
final Iterable<PluginProperty> properties, final CallContext callContext) throws EntitlementApiException {
logCreateEntitlement(log, null, planPhaseSpecifier, overrides, entitlementEffectiveDate, billingEffectiveDate);
@@ -183,12 +181,21 @@ public class DefaultEntitlementApi extends DefaultEntitlementApiBase implements
}
private EntitlementSpecifier getFirstEntitlementSpecifier(final Iterable<BaseEntitlementWithAddOnsSpecifier> baseEntitlementWithAddOnsSpecifiers) throws SubscriptionBaseApiException {
- if ((baseEntitlementWithAddOnsSpecifiers == null) || baseEntitlementWithAddOnsSpecifiers.iterator().hasNext()) {
- if ((baseEntitlementWithAddOnsSpecifiers.iterator().next().getEntitlementSpecifier() == null) || !baseEntitlementWithAddOnsSpecifiers.iterator().next().getEntitlementSpecifier().iterator().hasNext()) {
- throw new SubscriptionBaseApiException(ErrorCode.SUB_CREATE_INVALID_ENTITLEMENT_SPECIFIER);
- }
+ if (baseEntitlementWithAddOnsSpecifiers == null) {
+ throw new SubscriptionBaseApiException(ErrorCode.SUB_CREATE_INVALID_ENTITLEMENT_SPECIFIER);
+ }
+
+ final Iterator<BaseEntitlementWithAddOnsSpecifier> iterator = baseEntitlementWithAddOnsSpecifiers.iterator();
+ if (!iterator.hasNext()) {
+ throw new SubscriptionBaseApiException(ErrorCode.SUB_CREATE_INVALID_ENTITLEMENT_SPECIFIER);
+ }
+
+ final BaseEntitlementWithAddOnsSpecifier entitlementWithAddOnsSpecifier = iterator.next();
+ if (entitlementWithAddOnsSpecifier.getEntitlementSpecifier() == null || !entitlementWithAddOnsSpecifier.getEntitlementSpecifier().iterator().hasNext()) {
+ throw new SubscriptionBaseApiException(ErrorCode.SUB_CREATE_INVALID_ENTITLEMENT_SPECIFIER);
+ } else {
+ return entitlementWithAddOnsSpecifier.getEntitlementSpecifier().iterator().next();
}
- return baseEntitlementWithAddOnsSpecifiers.iterator().next().getEntitlementSpecifier().iterator().next();
}
@Override
@@ -211,11 +218,11 @@ public class DefaultEntitlementApi extends DefaultEntitlementApiBase implements
try {
final List<SubscriptionBaseWithAddOns> subscriptionsWithAddOns = subscriptionBaseInternalApi.createBaseSubscriptionsWithAddOns(accountId, baseEntitlementWithAddOnsSpecifiers, contextWithValidAccountRecordId);
- Map<BlockingState, UUID> blockingStateMap = new HashMap<BlockingState, UUID>();
+ final Map<BlockingState, UUID> blockingStateMap = new HashMap<BlockingState, UUID>();
int i = 0;
- for (Iterator<BaseEntitlementWithAddOnsSpecifier> it = baseEntitlementWithAddOnsSpecifiers.iterator(); it.hasNext(); i++) {
- BaseEntitlementWithAddOnsSpecifier baseEntitlementWithAddOnsSpecifier = it.next();
- for (SubscriptionBase subscriptionBase : subscriptionsWithAddOns.get(i).getSubscriptionBaseList()) {
+ for (final Iterator<BaseEntitlementWithAddOnsSpecifier> it = baseEntitlementWithAddOnsSpecifiers.iterator(); it.hasNext(); i++) {
+ final BaseEntitlementWithAddOnsSpecifier baseEntitlementWithAddOnsSpecifier = it.next();
+ for (final SubscriptionBase subscriptionBase : subscriptionsWithAddOns.get(i).getSubscriptionBaseList()) {
final BlockingState blockingState = new DefaultBlockingState(subscriptionBase.getId(), BlockingStateType.SUBSCRIPTION,
DefaultEntitlementApi.ENT_STATE_START,
EntitlementService.ENTITLEMENT_SERVICE_NAME,
@@ -234,13 +241,13 @@ public class DefaultEntitlementApi extends DefaultEntitlementApiBase implements
return pluginExecution.executeWithPlugin(createBaseEntitlementsWithAddOns, pluginContext);
}
- private List<Entitlement> buildEntitlementList(final UUID accountId, final List<SubscriptionBaseWithAddOns> subscriptionsWithAddOns, final CallContext callContext) throws EntitlementApiException {
- List<Entitlement> result = new ArrayList<Entitlement>();
- for (SubscriptionBaseWithAddOns subscriptionWithAddOns : subscriptionsWithAddOns) {
- for (SubscriptionBase subscriptionBase : subscriptionWithAddOns.getSubscriptionBaseList()) {
- Entitlement entitlement = new DefaultEntitlement(accountId, subscriptionBase.getId(), eventsStreamBuilder, entitlementApi, pluginExecution,
- blockingStateDao, subscriptionBaseInternalApi, checker, notificationQueueService,
- entitlementUtils, dateHelper, clock, securityApi, internalCallContextFactory, callContext);
+ private List<Entitlement> buildEntitlementList(final UUID accountId, final Iterable<SubscriptionBaseWithAddOns> subscriptionsWithAddOns, final CallContext callContext) throws EntitlementApiException {
+ final List<Entitlement> result = new ArrayList<Entitlement>();
+ for (final SubscriptionBaseWithAddOns subscriptionWithAddOns : subscriptionsWithAddOns) {
+ for (final SubscriptionBase subscriptionBase : subscriptionWithAddOns.getSubscriptionBaseList()) {
+ final Entitlement entitlement = new DefaultEntitlement(accountId, subscriptionBase.getId(), eventsStreamBuilder, entitlementApi, pluginExecution,
+ blockingStateDao, subscriptionBaseInternalApi, checker, notificationQueueService,
+ entitlementUtils, dateHelper, clock, securityApi, internalCallContextFactory, callContext);
result.add(entitlement);
}
}
diff --git a/entitlement/src/main/resources/org/killbill/billing/entitlement/ddl.sql b/entitlement/src/main/resources/org/killbill/billing/entitlement/ddl.sql
index a122b32..8d2d2be 100644
--- a/entitlement/src/main/resources/org/killbill/billing/entitlement/ddl.sql
+++ b/entitlement/src/main/resources/org/killbill/billing/entitlement/ddl.sql
@@ -1,4 +1,4 @@
-/*! SET storage_engine=INNODB */;
+/*! SET default_storage_engine=INNODB */;
DROP TABLE IF EXISTS blocking_states;
CREATE TABLE blocking_states (
diff --git a/invoice/src/main/resources/org/killbill/billing/invoice/ddl.sql b/invoice/src/main/resources/org/killbill/billing/invoice/ddl.sql
index 89602db..1487f3c 100644
--- a/invoice/src/main/resources/org/killbill/billing/invoice/ddl.sql
+++ b/invoice/src/main/resources/org/killbill/billing/invoice/ddl.sql
@@ -1,4 +1,4 @@
-/*! SET storage_engine=INNODB */;
+/*! SET default_storage_engine=INNODB */;
DROP TABLE IF EXISTS invoice_items;
CREATE TABLE invoice_items (
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/BundleResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/BundleResource.java
index 97c3dad..04e39d5 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/BundleResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/BundleResource.java
@@ -118,13 +118,15 @@ public class BundleResource extends JaxRsResourceBase {
@ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid bundle id supplied"),
@ApiResponse(code = 404, message = "Bundle not found")})
public Response getBundle(@PathParam("bundleId") final String bundleId,
+ @QueryParam(QUERY_AUDIT) @DefaultValue("NONE") final AuditMode auditMode,
@javax.ws.rs.core.Context final HttpServletRequest request) throws SubscriptionApiException, AccountApiException, CatalogApiException {
final UUID id = UUID.fromString(bundleId);
final TenantContext tenantContext = this.context.createContext(request);
final SubscriptionBundle bundle = subscriptionApi.getSubscriptionBundle(id, tenantContext);
final Account account = accountUserApi.getAccountById(bundle.getAccountId(), tenantContext);
- final BundleJson json = new BundleJson(bundle, account.getCurrency(), null);
+ final AccountAuditLogs accountAuditLogs = auditUserApi.getAccountAuditLogs(bundle.getAccountId(), auditMode.getLevel(), tenantContext);
+ final BundleJson json = new BundleJson(bundle, account.getCurrency(), accountAuditLogs);
return Response.status(Status.OK).entity(json).build();
}
@@ -135,6 +137,7 @@ public class BundleResource extends JaxRsResourceBase {
@ApiResponses(value = {@ApiResponse(code = 404, message = "Bundle not found")})
public Response getBundleByKey(@QueryParam(QUERY_EXTERNAL_KEY) final String externalKey,
@QueryParam(QUERY_INCLUDED_DELETED) @DefaultValue("false") final Boolean includedDeleted,
+ @QueryParam(QUERY_AUDIT) @DefaultValue("NONE") final AuditMode auditMode,
@javax.ws.rs.core.Context final HttpServletRequest request) throws SubscriptionApiException, AccountApiException, CatalogApiException {
final TenantContext tenantContext = this.context.createContext(request);
@@ -146,11 +149,11 @@ public class BundleResource extends JaxRsResourceBase {
final SubscriptionBundle activeBundle = subscriptionApi.getActiveSubscriptionBundleForExternalKey(externalKey, tenantContext);
bundles = ImmutableList.of(activeBundle);
}
-
final List<BundleJson> result = new ArrayList<BundleJson>(bundles.size());
for (final SubscriptionBundle bundle : bundles) {
final Account account = accountUserApi.getAccountById(bundle.getAccountId(), tenantContext);
- final BundleJson json = new BundleJson(bundle, account.getCurrency(), null);
+ final AccountAuditLogs accountAuditLogs = auditUserApi.getAccountAuditLogs(bundle.getAccountId(), auditMode.getLevel(), tenantContext);
+ final BundleJson json = new BundleJson(bundle, account.getCurrency(), accountAuditLogs);
result.add(json);
}
return Response.status(Status.OK).entity(result).build();
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 6532449..6cd4f7c 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
@@ -86,12 +86,14 @@ import org.killbill.billing.jaxrs.util.JaxrsUriBuilder;
import org.killbill.billing.jaxrs.util.KillbillEventHandler;
import org.killbill.billing.payment.api.PaymentApi;
import org.killbill.billing.payment.api.PluginProperty;
+import org.killbill.billing.util.api.AuditLevel;
import org.killbill.billing.util.api.AuditUserApi;
import org.killbill.billing.util.api.CustomFieldApiException;
import org.killbill.billing.util.api.CustomFieldUserApi;
import org.killbill.billing.util.api.TagApiException;
import org.killbill.billing.util.api.TagDefinitionApiException;
import org.killbill.billing.util.api.TagUserApi;
+import org.killbill.billing.util.audit.AccountAuditLogs;
import org.killbill.billing.util.callcontext.CallContext;
import org.killbill.billing.util.callcontext.TenantContext;
import org.killbill.billing.util.userrequest.CompletionUserRequestBase;
@@ -148,12 +150,14 @@ public class SubscriptionResource extends JaxRsResourceBase {
@ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid subscription id supplied"),
@ApiResponse(code = 404, message = "Subscription not found")})
public Response getEntitlement(@PathParam("subscriptionId") final String subscriptionId,
+ @QueryParam(QUERY_AUDIT) @DefaultValue("NONE") final AuditMode auditMode,
@javax.ws.rs.core.Context final HttpServletRequest request) throws SubscriptionApiException, AccountApiException, CatalogApiException {
final UUID uuid = UUID.fromString(subscriptionId);
final TenantContext context = this.context.createContext(request);
final Subscription subscription = subscriptionApi.getSubscriptionForEntitlementId(uuid, context);
final Account account = accountUserApi.getAccountById(subscription.getAccountId(), context);
- final SubscriptionJson json = new SubscriptionJson(subscription, account.getCurrency(), null);
+ final AccountAuditLogs accountAuditLogs = auditUserApi.getAccountAuditLogs(subscription.getAccountId(), auditMode.getLevel(), context);
+ final SubscriptionJson json = new SubscriptionJson(subscription, account.getCurrency(), accountAuditLogs);
return Response.status(Status.OK).entity(json).build();
}
@@ -596,7 +600,7 @@ public class SubscriptionResource extends JaxRsResourceBase {
if (operationResponse.getStatus() != Status.OK.getStatusCode()) {
return operationResponse;
}
- return getEntitlement(subscriptionId, request);
+ return getEntitlement(subscriptionId, new AuditMode(AuditLevel.NONE.toString()), request);
}
};
diff --git a/payment/src/main/resources/org/killbill/billing/payment/ddl.sql b/payment/src/main/resources/org/killbill/billing/payment/ddl.sql
index 25af914..019e3cf 100644
--- a/payment/src/main/resources/org/killbill/billing/payment/ddl.sql
+++ b/payment/src/main/resources/org/killbill/billing/payment/ddl.sql
@@ -1,4 +1,4 @@
-/*! SET storage_engine=INNODB */;
+/*! SET default_storage_engine=INNODB */;
DROP TABLE IF EXISTS payment_attempts;
CREATE TABLE payment_attempts (
diff --git a/subscription/src/main/java/org/killbill/billing/subscription/api/SubscriptionBaseApiService.java b/subscription/src/main/java/org/killbill/billing/subscription/api/SubscriptionBaseApiService.java
index d1991cd..e3ad715 100644
--- a/subscription/src/main/java/org/killbill/billing/subscription/api/SubscriptionBaseApiService.java
+++ b/subscription/src/main/java/org/killbill/billing/subscription/api/SubscriptionBaseApiService.java
@@ -47,7 +47,7 @@ public interface SubscriptionBaseApiService {
CallContext context)
throws SubscriptionBaseApiException;
- public List<DefaultSubscriptionBaseWithAddOns> createPlansWithAddOns(UUID accountId, Iterable<SubscriptionAndAddOnsSpecifier> subscriptionsAndAddOns, CallContext context)
+ public List<SubscriptionBaseWithAddOns> createPlansWithAddOns(UUID accountId, Iterable<SubscriptionAndAddOnsSpecifier> subscriptionsAndAddOns, CallContext context)
throws SubscriptionBaseApiException;
public boolean cancel(DefaultSubscriptionBase subscription, CallContext context)
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 9ccf2a8..d8bcd5c 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
@@ -19,6 +19,7 @@
package org.killbill.billing.subscription.api.svcs;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
@@ -57,6 +58,7 @@ import org.killbill.billing.events.EffectiveSubscriptionInternalEvent;
import org.killbill.billing.invoice.api.DryRunArguments;
import org.killbill.billing.subscription.api.SubscriptionApiBase;
import org.killbill.billing.subscription.api.SubscriptionBase;
+import org.killbill.billing.subscription.api.SubscriptionBaseApiService;
import org.killbill.billing.subscription.api.SubscriptionBaseInternalApi;
import org.killbill.billing.subscription.api.SubscriptionBaseTransitionType;
import org.killbill.billing.subscription.api.SubscriptionBaseWithAddOns;
@@ -86,6 +88,7 @@ import org.killbill.billing.util.bcd.BillCycleDayCalculator;
import org.killbill.billing.util.callcontext.CallContext;
import org.killbill.billing.util.callcontext.InternalCallContextFactory;
import org.killbill.billing.util.callcontext.TenantContext;
+import org.killbill.billing.util.entity.Entity;
import org.killbill.billing.util.entity.Pagination;
import org.killbill.billing.util.entity.dao.DefaultPaginationHelper.SourcePaginationBuilder;
import org.killbill.clock.Clock;
@@ -133,7 +136,7 @@ public class DefaultSubscriptionInternalApi extends SubscriptionApiBase implemen
@Inject
public DefaultSubscriptionInternalApi(final SubscriptionDao dao,
- final DefaultSubscriptionBaseApiService apiService,
+ final SubscriptionBaseApiService apiService,
final NotificationQueueService notificationQueueService,
final Clock clock,
final CatalogService catalogService,
@@ -204,7 +207,7 @@ public class DefaultSubscriptionInternalApi extends SubscriptionApiBase implemen
boolean first = true;
final List<SubscriptionBase> subscriptionsForBundle = getSubscriptionsForBundle(bundleId, null, context);
- for (EntitlementSpecifier entitlement : entitlements) {
+ for (final EntitlementSpecifier entitlement : entitlements) {
final PlanPhaseSpecifier spec = entitlement.getPlanPhaseSpecifier();
@@ -227,8 +230,8 @@ public class DefaultSubscriptionInternalApi extends SubscriptionApiBase implemen
// verify the number of subscriptions (of the same kind) allowed per bundle and the existing ones
if (ProductCategory.ADD_ON.toString().equalsIgnoreCase(plan.getProduct().getCategory().toString())) {
if (plan.getPlansAllowedInBundle() != -1 && plan.getPlansAllowedInBundle() > 0) {
- int existingAddOnsWithSamePlanName = addonUtils.countExistingAddOnsWithSamePlanName(subscriptionsForBundle, plan.getName());
- int currentAddOnsWithSamePlanName = countCurrentAddOnsWithSamePlanName(entitlements, catalog, plan.getName(), effectiveDate, callContext);
+ final int existingAddOnsWithSamePlanName = addonUtils.countExistingAddOnsWithSamePlanName(subscriptionsForBundle, plan.getName());
+ final int currentAddOnsWithSamePlanName = countCurrentAddOnsWithSamePlanName(entitlements, catalog, plan.getName(), effectiveDate, callContext);
if ((existingAddOnsWithSamePlanName + currentAddOnsWithSamePlanName) > plan.getPlansAllowedInBundle()) {
// a new ADD_ON subscription of the same plan can't be added because it has reached its limit by bundle
throw new SubscriptionBaseApiException(ErrorCode.SUB_CREATE_AO_MAX_PLAN_ALLOWED_BY_BUNDLE, plan.getName());
@@ -236,7 +239,7 @@ public class DefaultSubscriptionInternalApi extends SubscriptionApiBase implemen
}
}
- SubscriptionSpecifier subscription = new SubscriptionSpecifier();
+ final SubscriptionSpecifier subscription = new SubscriptionSpecifier();
subscription.setRealPriceList(plan.getPriceListName());
subscription.setEffectiveDate(effectiveDate);
subscription.setProcessedDate(now);
@@ -262,14 +265,14 @@ public class DefaultSubscriptionInternalApi extends SubscriptionApiBase implemen
final CallContext callContext = internalCallContextFactory.createCallContext(context);
final DateTime now = clock.getUTCNow();
- final List<SubscriptionAndAddOnsSpecifier> subscriptionAndAddOns = new ArrayList<SubscriptionAndAddOnsSpecifier>();
- for (BaseEntitlementWithAddOnsSpecifier entitlementWithAddOnsSpecifier : baseEntitlementWithAddOnsSpecifier) {
+ final Collection<SubscriptionAndAddOnsSpecifier> subscriptionAndAddOns = new ArrayList<SubscriptionAndAddOnsSpecifier>();
+ for (final BaseEntitlementWithAddOnsSpecifier entitlementWithAddOnsSpecifier : baseEntitlementWithAddOnsSpecifier) {
final DateTime effectiveDate = (entitlementWithAddOnsSpecifier.getBillingEffectiveDate() != null) ?
DefaultClock.truncateMs(entitlementWithAddOnsSpecifier.getBillingEffectiveDate().toDateTimeAtStartOfDay()) : now;
final SubscriptionBaseBundle bundle = createBundleForAccount(accountId, entitlementWithAddOnsSpecifier.getExternalKey(), context);
- SubscriptionAndAddOnsSpecifier subscriptionAndAddOnsSpecifier = new SubscriptionAndAddOnsSpecifier(
+ final SubscriptionAndAddOnsSpecifier subscriptionAndAddOnsSpecifier = new SubscriptionAndAddOnsSpecifier(
bundle.getId(),
effectiveDate,
verifyAndBuildSubscriptionSpecifiers(bundle.getId(),
@@ -284,27 +287,8 @@ public class DefaultSubscriptionInternalApi extends SubscriptionApiBase implemen
subscriptionAndAddOns.add(subscriptionAndAddOnsSpecifier);
}
- final List<DefaultSubscriptionBaseWithAddOns> defaultSubscriptionBaseWithAddOnsList = apiService.createPlansWithAddOns(accountId, subscriptionAndAddOns, callContext);
- List<SubscriptionBaseWithAddOns> subscriptionBaseWithAddOnsList = new ArrayList<SubscriptionBaseWithAddOns>();
- for (final DefaultSubscriptionBaseWithAddOns cur : defaultSubscriptionBaseWithAddOnsList) {
- SubscriptionBaseWithAddOns subscriptionBaseWithAddOns = new SubscriptionBaseWithAddOns() {
- @Override
- public UUID getBundleId() {
- return cur.getBundleId();
- }
- @Override
- public List<SubscriptionBase> getSubscriptionBaseList() {
- return cur.getSubscriptionBaseList();
- }
- @Override
- public DateTime getEffectiveDate() {
- return cur.getEffectiveDate();
- }
- };
- subscriptionBaseWithAddOnsList.add(subscriptionBaseWithAddOns);
- }
- return subscriptionBaseWithAddOnsList;
- } catch (CatalogApiException e) {
+ return apiService.createPlansWithAddOns(accountId, subscriptionAndAddOns, callContext);
+ } catch (final CatalogApiException e) {
throw new SubscriptionBaseApiException(e);
}
}
@@ -313,7 +297,7 @@ public class DefaultSubscriptionInternalApi extends SubscriptionApiBase implemen
final Catalog catalog, final String planName,
final DateTime effectiveDate, final CallContext callContext) throws CatalogApiException {
int countCurrentAddOns = 0;
- for (EntitlementSpecifier entitlement : entitlements) {
+ for (final EntitlementSpecifier entitlement : entitlements) {
final PlanPhaseSpecifier spec = entitlement.getPlanPhaseSpecifier();
final PlanPhasePriceOverridesWithCallContext overridesWithContext =
new DefaultPlanPhasePriceOverridesWithCallContext(entitlement.getOverrides(), callContext);
@@ -350,7 +334,7 @@ public class DefaultSubscriptionInternalApi extends SubscriptionApiBase implemen
final List<SubscriptionBaseBundle> existingBundles = dao.getSubscriptionBundlesForKey(bundleKey, context);
final DateTime now = clock.getUTCNow();
- final DateTime originalCreatedDate = existingBundles.size() > 0 ? existingBundles.get(0).getCreatedDate() : now;
+ final DateTime originalCreatedDate = !existingBundles.isEmpty() ? existingBundles.get(0).getCreatedDate() : now;
final DefaultSubscriptionBaseBundle bundle = new DefaultSubscriptionBaseBundle(bundleKey, accountId, now, originalCreatedDate, now, now);
if (null != bundleKey && bundleKey.length() > 255) {
@@ -361,8 +345,7 @@ public class DefaultSubscriptionInternalApi extends SubscriptionApiBase implemen
@Override
public List<SubscriptionBaseBundle> getBundlesForAccountAndKey(final UUID accountId, final String bundleKey, final InternalTenantContext context) throws SubscriptionBaseApiException {
- final List<SubscriptionBaseBundle> bundlesForAccountAndKey = dao.getSubscriptionBundlesForAccountAndKey(accountId, bundleKey, context);
- return bundlesForAccountAndKey;
+ return dao.getSubscriptionBundlesForAccountAndKey(accountId, bundleKey, context);
}
@Override
@@ -372,8 +355,7 @@ public class DefaultSubscriptionInternalApi extends SubscriptionApiBase implemen
@Override
public List<SubscriptionBaseBundle> getBundlesForKey(final String bundleKey, final InternalTenantContext context) {
- final List<SubscriptionBaseBundle> result = dao.getSubscriptionBundlesForKey(bundleKey, context);
- return result;
+ return dao.getSubscriptionBundlesForKey(bundleKey, context);
}
@Override
@@ -418,7 +400,7 @@ public class DefaultSubscriptionInternalApi extends SubscriptionApiBase implemen
return dao.getNonAOSubscriptionIdsForKey(bundleKey, context);
}
- public static SubscriptionBaseBundle getActiveBundleForKeyNotException(final List<SubscriptionBaseBundle> existingBundles, final SubscriptionDao dao, final Clock clock, final InternalTenantContext context) {
+ public static SubscriptionBaseBundle getActiveBundleForKeyNotException(final Iterable<SubscriptionBaseBundle> existingBundles, final SubscriptionDao dao, final Clock clock, final InternalTenantContext context) {
for (final SubscriptionBaseBundle cur : existingBundles) {
final List<SubscriptionBase> subscriptions;
try {
@@ -531,7 +513,7 @@ public class DefaultSubscriptionInternalApi extends SubscriptionApiBase implemen
@Override
public List<EffectiveSubscriptionInternalEvent> getAllTransitions(final SubscriptionBase subscription, final InternalTenantContext context) {
- final List<SubscriptionBaseTransition> transitions = ((DefaultSubscriptionBase) subscription).getAllTransitions();
+ final List<SubscriptionBaseTransition> transitions = subscription.getAllTransitions();
return convertEffectiveSubscriptionInternalEventFromSubscriptionTransitions(subscription, context, transitions);
}
@@ -623,8 +605,8 @@ public class DefaultSubscriptionInternalApi extends SubscriptionApiBase implemen
private void populateDryRunEvents(@Nullable final UUID bundleId,
@Nullable final DryRunArguments dryRunArguments,
- final List<SubscriptionBaseEvent> outputDryRunEvents,
- final List<SubscriptionBase> outputSubscriptions,
+ final Collection<SubscriptionBaseEvent> outputDryRunEvents,
+ final Collection<SubscriptionBase> outputSubscriptions,
final InternalTenantContext context) throws SubscriptionBaseApiException {
if (dryRunArguments == null || dryRunArguments.getAction() == null) {
return;
@@ -645,62 +627,59 @@ public class DefaultSubscriptionInternalApi extends SubscriptionApiBase implemen
catalog.createOrFindPlan(inputSpec, overridesWithContext, utcNow);
final TenantContext tenantContext = internalCallContextFactory.createTenantContext(context);
-
- if (dryRunArguments != null) {
- switch (dryRunArguments.getAction()) {
- case START_BILLING:
-
- final DefaultSubscriptionBase baseSubscription = (DefaultSubscriptionBase) dao.getBaseSubscription(bundleId, context);
- final DateTime startEffectiveDate = dryRunArguments.getEffectiveDate() != null ? context.toUTCDateTime(dryRunArguments.getEffectiveDate()) : utcNow;
- final DateTime bundleStartDate = getBundleStartDateWithSanity(bundleId, baseSubscription, plan, startEffectiveDate, context);
- final UUID subscriptionId = UUIDs.randomUUID();
- dryRunEvents = apiService.getEventsOnCreation(bundleId, subscriptionId, startEffectiveDate, bundleStartDate, plan, inputSpec.getPhaseType(), plan.getPriceListName(),
- startEffectiveDate, utcNow, context);
- final SubscriptionBuilder builder = new SubscriptionBuilder()
- .setId(subscriptionId)
- .setBundleId(bundleId)
- .setCategory(plan.getProduct().getCategory())
- .setBundleStartDate(bundleStartDate)
- .setAlignStartDate(startEffectiveDate);
- final DefaultSubscriptionBase newSubscription = new DefaultSubscriptionBase(builder, apiService, clock);
- newSubscription.rebuildTransitions(dryRunEvents, catalog);
- outputSubscriptions.add(newSubscription);
- break;
-
- case CHANGE:
- final DefaultSubscriptionBase subscriptionForChange = (DefaultSubscriptionBase) dao.getSubscriptionFromId(dryRunArguments.getSubscriptionId(), context);
- DateTime changeEffectiveDate = dryRunArguments.getEffectiveDate() != null ? context.toUTCDateTime(dryRunArguments.getEffectiveDate()) : null;
- if (changeEffectiveDate == null) {
- BillingActionPolicy policy = dryRunArguments.getBillingActionPolicy();
- if (policy == null) {
- final PlanChangeResult planChangeResult = apiService.getPlanChangeResult(subscriptionForChange, inputSpec, utcNow, tenantContext);
- policy = planChangeResult.getPolicy();
- }
- changeEffectiveDate = subscriptionForChange.getPlanChangeEffectiveDate(policy);
+ switch (dryRunArguments.getAction()) {
+ case START_BILLING:
+
+ final DefaultSubscriptionBase baseSubscription = (DefaultSubscriptionBase) dao.getBaseSubscription(bundleId, context);
+ final DateTime startEffectiveDate = dryRunArguments.getEffectiveDate() != null ? context.toUTCDateTime(dryRunArguments.getEffectiveDate()) : utcNow;
+ final DateTime bundleStartDate = getBundleStartDateWithSanity(bundleId, baseSubscription, plan, startEffectiveDate, context);
+ final UUID subscriptionId = UUIDs.randomUUID();
+ dryRunEvents = apiService.getEventsOnCreation(bundleId, subscriptionId, startEffectiveDate, bundleStartDate, plan, inputSpec.getPhaseType(), plan.getPriceListName(),
+ startEffectiveDate, utcNow, context);
+ final SubscriptionBuilder builder = new SubscriptionBuilder()
+ .setId(subscriptionId)
+ .setBundleId(bundleId)
+ .setCategory(plan.getProduct().getCategory())
+ .setBundleStartDate(bundleStartDate)
+ .setAlignStartDate(startEffectiveDate);
+ final DefaultSubscriptionBase newSubscription = new DefaultSubscriptionBase(builder, apiService, clock);
+ newSubscription.rebuildTransitions(dryRunEvents, catalog);
+ outputSubscriptions.add(newSubscription);
+ break;
+
+ case CHANGE:
+ final DefaultSubscriptionBase subscriptionForChange = (DefaultSubscriptionBase) dao.getSubscriptionFromId(dryRunArguments.getSubscriptionId(), context);
+ DateTime changeEffectiveDate = dryRunArguments.getEffectiveDate() != null ? context.toUTCDateTime(dryRunArguments.getEffectiveDate()) : null;
+ if (changeEffectiveDate == null) {
+ BillingActionPolicy policy = dryRunArguments.getBillingActionPolicy();
+ if (policy == null) {
+ final PlanChangeResult planChangeResult = apiService.getPlanChangeResult(subscriptionForChange, inputSpec, utcNow, tenantContext);
+ policy = planChangeResult.getPolicy();
}
- dryRunEvents = apiService.getEventsOnChangePlan(subscriptionForChange, plan, plan.getPriceListName(), changeEffectiveDate, utcNow, true, context);
- break;
-
- case STOP_BILLING:
- final DefaultSubscriptionBase subscriptionForCancellation = (DefaultSubscriptionBase) dao.getSubscriptionFromId(dryRunArguments.getSubscriptionId(), context);
- DateTime cancelEffectiveDate = dryRunArguments.getEffectiveDate() != null ? context.toUTCDateTime(dryRunArguments.getEffectiveDate()) : null;
- if (dryRunArguments.getEffectiveDate() == null) {
- BillingActionPolicy policy = dryRunArguments.getBillingActionPolicy();
- if (policy == null) {
-
- final Plan currentPlan = subscriptionForCancellation.getCurrentPlan();
- final PlanPhaseSpecifier spec = new PlanPhaseSpecifier(currentPlan.getName(),
- subscriptionForCancellation.getCurrentPhase().getPhaseType());
- policy = catalogService.getFullCatalog(true, true, context).planCancelPolicy(spec, utcNow);
- }
- cancelEffectiveDate = subscriptionForCancellation.getPlanChangeEffectiveDate(policy);
+ changeEffectiveDate = subscriptionForChange.getPlanChangeEffectiveDate(policy);
+ }
+ dryRunEvents = apiService.getEventsOnChangePlan(subscriptionForChange, plan, plan.getPriceListName(), changeEffectiveDate, utcNow, true, context);
+ break;
+
+ case STOP_BILLING:
+ final DefaultSubscriptionBase subscriptionForCancellation = (DefaultSubscriptionBase) dao.getSubscriptionFromId(dryRunArguments.getSubscriptionId(), context);
+ DateTime cancelEffectiveDate = dryRunArguments.getEffectiveDate() != null ? context.toUTCDateTime(dryRunArguments.getEffectiveDate()) : null;
+ if (dryRunArguments.getEffectiveDate() == null) {
+ BillingActionPolicy policy = dryRunArguments.getBillingActionPolicy();
+ if (policy == null) {
+
+ final Plan currentPlan = subscriptionForCancellation.getCurrentPlan();
+ final PlanPhaseSpecifier spec = new PlanPhaseSpecifier(currentPlan.getName(),
+ subscriptionForCancellation.getCurrentPhase().getPhaseType());
+ policy = catalogService.getFullCatalog(true, true, context).planCancelPolicy(spec, utcNow);
}
- dryRunEvents = apiService.getEventsOnCancelPlan(subscriptionForCancellation, cancelEffectiveDate, utcNow, true, context);
- break;
+ cancelEffectiveDate = subscriptionForCancellation.getPlanChangeEffectiveDate(policy);
+ }
+ dryRunEvents = apiService.getEventsOnCancelPlan(subscriptionForCancellation, cancelEffectiveDate, utcNow, true, context);
+ break;
- default:
- throw new IllegalArgumentException("Unexpected dryRunArguments action " + dryRunArguments.getAction());
- }
+ default:
+ throw new IllegalArgumentException("Unexpected dryRunArguments action " + dryRunArguments.getAction());
}
} catch (final CatalogApiException e) {
throw new SubscriptionBaseApiException(e);
@@ -723,7 +702,7 @@ public class DefaultSubscriptionInternalApi extends SubscriptionApiBase implemen
return input.getEffectiveDate();
}
});
- } catch (NoSuchNotificationQueue noSuchNotificationQueue) {
+ } catch (final NoSuchNotificationQueue noSuchNotificationQueue) {
throw new IllegalStateException(noSuchNotificationQueue);
}
}
@@ -746,7 +725,7 @@ public class DefaultSubscriptionInternalApi extends SubscriptionApiBase implemen
}
});
final Map<UUID, DateTime> result = filteredEvents.iterator().hasNext() ? new HashMap<UUID, DateTime>() : ImmutableMap.<UUID, DateTime>of();
- for (SubscriptionBaseEvent cur : filteredEvents) {
+ for (final SubscriptionBaseEvent cur : filteredEvents) {
final DateTime targetDate = result.get(cur.getSubscriptionId());
if (targetDate == null || targetDate.compareTo(cur.getEffectiveDate()) > 0) {
result.put(cur.getSubscriptionId(), cur.getEffectiveDate());
@@ -840,7 +819,7 @@ public class DefaultSubscriptionInternalApi extends SubscriptionApiBase implemen
}
private List<EffectiveSubscriptionInternalEvent> convertEffectiveSubscriptionInternalEventFromSubscriptionTransitions(final SubscriptionBase subscription,
- final InternalTenantContext context, final List<SubscriptionBaseTransition> transitions) {
+ final InternalTenantContext context, final Collection<SubscriptionBaseTransition> transitions) {
return ImmutableList.<EffectiveSubscriptionInternalEvent>copyOf(Collections2.transform(transitions, new Function<SubscriptionBaseTransition, EffectiveSubscriptionInternalEvent>() {
@Override
@Nullable
@@ -851,7 +830,7 @@ public class DefaultSubscriptionInternalApi extends SubscriptionApiBase implemen
}
// For forward-compatibility
- private DefaultSubscriptionBase getDefaultSubscriptionBase(final SubscriptionBase subscriptionBase, final InternalTenantContext context) throws CatalogApiException {
+ private DefaultSubscriptionBase getDefaultSubscriptionBase(final Entity subscriptionBase, final InternalTenantContext context) throws CatalogApiException {
if (subscriptionBase instanceof DefaultSubscriptionBase) {
return (DefaultSubscriptionBase) subscriptionBase;
} else {
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 0cd9ce2..49efce2 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
@@ -29,6 +29,7 @@ import java.util.UUID;
import javax.annotation.Nullable;
import org.joda.time.DateTime;
+import org.joda.time.ReadableInstant;
import org.killbill.billing.ErrorCode;
import org.killbill.billing.ObjectType;
import org.killbill.billing.callcontext.InternalCallContext;
@@ -36,6 +37,7 @@ import org.killbill.billing.callcontext.InternalTenantContext;
import org.killbill.billing.catalog.api.BillingActionPolicy;
import org.killbill.billing.catalog.api.Catalog;
import org.killbill.billing.catalog.api.CatalogApiException;
+import org.killbill.billing.catalog.api.CatalogEntity;
import org.killbill.billing.catalog.api.CatalogService;
import org.killbill.billing.catalog.api.PhaseType;
import org.killbill.billing.catalog.api.Plan;
@@ -44,7 +46,6 @@ import org.killbill.billing.catalog.api.PlanPhasePriceOverride;
import org.killbill.billing.catalog.api.PlanPhasePriceOverridesWithCallContext;
import org.killbill.billing.catalog.api.PlanPhaseSpecifier;
import org.killbill.billing.catalog.api.PlanSpecifier;
-import org.killbill.billing.catalog.api.PriceList;
import org.killbill.billing.catalog.api.Product;
import org.killbill.billing.catalog.api.ProductCategory;
import org.killbill.billing.entitlement.api.Entitlement.EntitlementState;
@@ -52,13 +53,13 @@ import org.killbill.billing.subscription.alignment.PlanAligner;
import org.killbill.billing.subscription.alignment.TimedPhase;
import org.killbill.billing.subscription.api.SubscriptionBase;
import org.killbill.billing.subscription.api.SubscriptionBaseApiService;
+import org.killbill.billing.subscription.api.SubscriptionBaseWithAddOns;
import org.killbill.billing.subscription.api.svcs.DefaultPlanPhasePriceOverridesWithCallContext;
import org.killbill.billing.subscription.engine.addon.AddonUtils;
import org.killbill.billing.subscription.engine.dao.SubscriptionDao;
import org.killbill.billing.subscription.events.SubscriptionBaseEvent;
import org.killbill.billing.subscription.events.phase.PhaseEvent;
import org.killbill.billing.subscription.events.phase.PhaseEventData;
-import org.killbill.billing.subscription.events.user.ApiEvent;
import org.killbill.billing.subscription.events.user.ApiEventBuilder;
import org.killbill.billing.subscription.events.user.ApiEventCancel;
import org.killbill.billing.subscription.events.user.ApiEventChange;
@@ -70,7 +71,6 @@ import org.killbill.billing.util.callcontext.TenantContext;
import org.killbill.clock.Clock;
import org.killbill.clock.DefaultClock;
-import com.google.common.base.Function;
import com.google.common.base.Predicate;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
@@ -118,41 +118,34 @@ public class DefaultSubscriptionBaseApiService implements SubscriptionBaseApiSer
}
@Override
- public List<DefaultSubscriptionBaseWithAddOns> createPlansWithAddOns(final UUID accountId, final Iterable<SubscriptionAndAddOnsSpecifier> subscriptionsAndAddOns, final CallContext context) throws SubscriptionBaseApiException {
- Map<UUID, List<SubscriptionBaseEvent>> eventsMap = new HashMap<UUID, List<SubscriptionBaseEvent>>();
- List<List<DefaultSubscriptionBase>> subscriptionBaseAndAddOnsList = new ArrayList<List<DefaultSubscriptionBase>>();
- List<DefaultSubscriptionBaseWithAddOns> allSubscriptions = new ArrayList<DefaultSubscriptionBaseWithAddOns>();
+ public List<SubscriptionBaseWithAddOns> createPlansWithAddOns(final UUID accountId, final Iterable<SubscriptionAndAddOnsSpecifier> subscriptionsAndAddOns, final CallContext context) throws SubscriptionBaseApiException {
+ final Map<UUID, List<SubscriptionBaseEvent>> eventsMap = new HashMap<UUID, List<SubscriptionBaseEvent>>();
+ final Collection<List<SubscriptionBase>> subscriptionBaseAndAddOnsList = new ArrayList<List<SubscriptionBase>>();
- for (SubscriptionAndAddOnsSpecifier subscriptionAndAddOns : subscriptionsAndAddOns) {
- List<DefaultSubscriptionBase> subscriptionBaseList = new ArrayList<DefaultSubscriptionBase>();
+ final List<SubscriptionBaseWithAddOns> allSubscriptions = new ArrayList<SubscriptionBaseWithAddOns>();
+ for (final SubscriptionAndAddOnsSpecifier subscriptionAndAddOns : subscriptionsAndAddOns) {
+ final List<SubscriptionBase> subscriptionBaseList = new ArrayList<SubscriptionBase>();
createEvents(subscriptionAndAddOns.getSubscriptionSpecifiers(), context, eventsMap, subscriptionBaseList);
-
subscriptionBaseAndAddOnsList.add(subscriptionBaseList);
- DefaultSubscriptionBaseWithAddOns defaultSubscriptionBaseWithAddOns = new DefaultSubscriptionBaseWithAddOns(
- subscriptionAndAddOns.getBundleId(),
- ImmutableList.copyOf(Iterables.transform(subscriptionBaseList, new Function<DefaultSubscriptionBase, SubscriptionBase>() {
- @Override
- public SubscriptionBase apply(final DefaultSubscriptionBase input) {
- return input;
- }
- })),
- subscriptionAndAddOns.getEffectiveDate());
- allSubscriptions.add(defaultSubscriptionBaseWithAddOns);
+ final SubscriptionBaseWithAddOns subscriptionBaseWithAddOns = new DefaultSubscriptionBaseWithAddOns(subscriptionAndAddOns.getBundleId(),
+ subscriptionBaseList,
+ subscriptionAndAddOns.getEffectiveDate());
+ allSubscriptions.add(subscriptionBaseWithAddOns);
}
final InternalCallContext internalCallContext = createCallContextFromAccountId(accountId, context);
dao.createSubscriptionsWithAddOns(allSubscriptions, eventsMap, internalCallContext);
- for (List<DefaultSubscriptionBase> subscriptions : subscriptionBaseAndAddOnsList) {
- final DefaultSubscriptionBase baseSubscription = findBaseSubscription(subscriptions);
+ for (final List<SubscriptionBase> subscriptions : subscriptionBaseAndAddOnsList) {
+ final SubscriptionBase baseSubscription = findBaseSubscription(subscriptions);
rebuildTransitions(internalCallContext, subscriptions, baseSubscription);
}
return allSubscriptions;
}
- private void createEvents(final Iterable<SubscriptionSpecifier> subscriptions, final CallContext context, final Map<UUID, List<SubscriptionBaseEvent>> eventsMap, final List<DefaultSubscriptionBase> subscriptionBaseList) throws SubscriptionBaseApiException {
- for (SubscriptionSpecifier subscription : subscriptions) {
+ private void createEvents(final Iterable<SubscriptionSpecifier> subscriptions, final CallContext context, final Map<UUID, List<SubscriptionBaseEvent>> eventsMap, final Collection<SubscriptionBase> subscriptionBaseList) throws SubscriptionBaseApiException {
+ for (final SubscriptionSpecifier subscription : subscriptions) {
try {
final DefaultSubscriptionBase subscriptionBase = new DefaultSubscriptionBase(subscription.getBuilder(), this, clock);
final InternalCallContext internalCallContext = createCallContextFromBundleId(subscriptionBase.getBundleId(), context);
@@ -162,32 +155,33 @@ public class DefaultSubscriptionBaseApiService implements SubscriptionBaseApiSer
subscription.getEffectiveDate(), subscription.getProcessedDate(), internalCallContext);
eventsMap.put(subscriptionBase.getId(), events);
subscriptionBaseList.add(subscriptionBase);
-
} catch (final CatalogApiException e) {
throw new SubscriptionBaseApiException(e);
}
}
}
- private void rebuildTransitions(final InternalCallContext internalCallContext, final List<DefaultSubscriptionBase> subscriptions, final DefaultSubscriptionBase baseSubscription) throws SubscriptionBaseApiException {
+ private void rebuildTransitions(final InternalCallContext internalCallContext, final Iterable<SubscriptionBase> subscriptions, final SubscriptionBase baseSubscription) throws SubscriptionBaseApiException {
try {
- baseSubscription.rebuildTransitions(dao.getEventsForSubscription(baseSubscription.getId(), internalCallContext),
- catalogService.getFullCatalog(true, true, internalCallContext));
+ // Safe cast
+ ((DefaultSubscriptionBase) baseSubscription).rebuildTransitions(dao.getEventsForSubscription(baseSubscription.getId(), internalCallContext),
+ catalogService.getFullCatalog(true, true, internalCallContext));
- for (final DefaultSubscriptionBase input : subscriptions) {
+ for (final SubscriptionBase input : subscriptions) {
if (input.getId().equals(baseSubscription.getId())) {
continue;
}
- input.rebuildTransitions(dao.getEventsForSubscription(input.getId(), internalCallContext),
- catalogService.getFullCatalog(true, true, internalCallContext));
+ // Safe cast
+ ((DefaultSubscriptionBase) input).rebuildTransitions(dao.getEventsForSubscription(input.getId(), internalCallContext),
+ catalogService.getFullCatalog(true, true, internalCallContext));
}
- } catch (CatalogApiException e) {
+ } catch (final CatalogApiException e) {
throw new SubscriptionBaseApiException(e);
}
}
- private DefaultSubscriptionBase findBaseSubscription(final List<DefaultSubscriptionBase> subscriptionBaseList) {
+ private SubscriptionBase findBaseSubscription(final Iterable<SubscriptionBase> subscriptionBaseList) {
return Iterables.tryFind(subscriptionBaseList, new Predicate<SubscriptionBase>() {
@Override
public boolean apply(final SubscriptionBase subscription) {
@@ -400,7 +394,6 @@ public class DefaultSubscriptionBaseApiService implements SubscriptionBaseApiSer
final InternalTenantContext internalCallContext = createTenantContextFromBundleId(subscription.getBundleId(), context);
final Plan currentPlan = subscription.getCurrentPlan();
- final PriceList currentPriceList = subscription.getCurrentPriceList();
final PlanPhaseSpecifier fromPlanPhase = new PlanPhaseSpecifier(currentPlan.getName(),
subscription.getCurrentPhase().getPhaseType());
planChangeResult = catalogService.getFullCatalog(true, true, internalCallContext).planChange(fromPlanPhase, toPlanPhase, effectiveDate);
@@ -459,7 +452,7 @@ public class DefaultSubscriptionBaseApiService implements SubscriptionBaseApiSer
.setEventPriceList(realPriceList)
.setEffectiveDate(effectiveDate)
.setFromDisk(true);
- final ApiEvent creationEvent = new ApiEventCreate(createBuilder);
+ final SubscriptionBaseEvent creationEvent = new ApiEventCreate(createBuilder);
final TimedPhase nextTimedPhase = curAndNextPhases[1];
final PhaseEvent nextPhaseEvent = (nextTimedPhase != null) ?
@@ -478,7 +471,7 @@ public class DefaultSubscriptionBaseApiService implements SubscriptionBaseApiSer
final String newPriceList, final DateTime effectiveDate, final DateTime processedDate,
final boolean addCancellationAddOnForEventsIfRequired, final InternalTenantContext internalTenantContext) throws CatalogApiException, SubscriptionBaseApiException {
final Collection<DefaultSubscriptionBase> addOnSubscriptionsToBeCancelled = new ArrayList<DefaultSubscriptionBase>();
- final List<SubscriptionBaseEvent> addOnCancelEvents = new ArrayList<SubscriptionBaseEvent>();
+ final Collection<SubscriptionBaseEvent> addOnCancelEvents = new ArrayList<SubscriptionBaseEvent>();
final List<SubscriptionBaseEvent> changeEvents = getEventsOnChangePlan(subscription, newPlan, newPriceList, effectiveDate, addCancellationAddOnForEventsIfRequired, addOnSubscriptionsToBeCancelled, addOnCancelEvents, internalTenantContext);
changeEvents.addAll(addOnCancelEvents);
@@ -489,7 +482,7 @@ public class DefaultSubscriptionBaseApiService implements SubscriptionBaseApiSer
final String newPriceList, final DateTime effectiveDate,
final boolean addCancellationAddOnForEventsIfRequired,
final Collection<DefaultSubscriptionBase> addOnSubscriptionsToBeCancelled,
- final List<SubscriptionBaseEvent> addOnCancelEvents,
+ final Collection<SubscriptionBaseEvent> addOnCancelEvents,
final InternalTenantContext internalTenantContext) throws CatalogApiException, SubscriptionBaseApiException {
final TimedPhase currentTimedPhase = planAligner.getCurrentTimedPhaseOnChange(subscription, newPlan, newPriceList, effectiveDate, internalTenantContext);
@@ -550,7 +543,7 @@ public class DefaultSubscriptionBaseApiService implements SubscriptionBaseApiSer
return subscriptionsToBeCancelled.size();
}
- private List<DefaultSubscriptionBase> computeAddOnsToCancel(final List<SubscriptionBaseEvent> cancelEvents, final Product baseProduct, final UUID bundleId, final DateTime effectiveDate, final InternalCallContext internalCallContext) throws CatalogApiException {
+ private List<DefaultSubscriptionBase> computeAddOnsToCancel(final Collection<SubscriptionBaseEvent> cancelEvents, final CatalogEntity baseProduct, final UUID bundleId, final DateTime effectiveDate, 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) {
@@ -560,7 +553,7 @@ public class DefaultSubscriptionBaseApiService implements SubscriptionBaseApiSer
}
}
- private List<DefaultSubscriptionBase> addCancellationAddOnForEventsIfRequired(final List<SubscriptionBaseEvent> events, final Product baseProduct, final UUID bundleId,
+ private List<DefaultSubscriptionBase> addCancellationAddOnForEventsIfRequired(final Collection<SubscriptionBaseEvent> events, final CatalogEntity baseProduct, final UUID bundleId,
final DateTime effectiveDate, final InternalTenantContext internalTenantContext) throws CatalogApiException {
final List<DefaultSubscriptionBase> subscriptionsToBeCancelled = new ArrayList<DefaultSubscriptionBase>();
@@ -592,7 +585,7 @@ public class DefaultSubscriptionBaseApiService implements SubscriptionBaseApiSer
return subscriptionsToBeCancelled;
}
- private void validateEffectiveDate(final DefaultSubscriptionBase subscription, final DateTime effectiveDate) throws SubscriptionBaseApiException {
+ private void validateEffectiveDate(final SubscriptionBase subscription, final ReadableInstant effectiveDate) throws SubscriptionBaseApiException {
final SubscriptionBaseTransition previousTransition = subscription.getPreviousTransition();
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 81df1b3..9c842a1 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
@@ -46,6 +46,7 @@ import org.killbill.billing.entitlement.api.SubscriptionApiException;
import org.killbill.billing.entity.EntityPersistenceException;
import org.killbill.billing.subscription.api.SubscriptionBase;
import org.killbill.billing.subscription.api.SubscriptionBaseTransitionType;
+import org.killbill.billing.subscription.api.SubscriptionBaseWithAddOns;
import org.killbill.billing.subscription.api.svcs.DefaultSubscriptionInternalApi;
import org.killbill.billing.subscription.api.transfer.BundleTransferData;
import org.killbill.billing.subscription.api.transfer.SubscriptionTransferData;
@@ -80,9 +81,11 @@ import org.killbill.billing.subscription.exceptions.SubscriptionBaseError;
import org.killbill.billing.util.cache.CacheControllerDispatcher;
import org.killbill.billing.util.callcontext.InternalCallContextFactory;
import org.killbill.billing.util.dao.NonEntityDao;
+import org.killbill.billing.util.entity.Entity;
import org.killbill.billing.util.entity.Pagination;
import org.killbill.billing.util.entity.dao.DefaultPaginationSqlDaoHelper.PaginationIteratorBuilder;
import org.killbill.billing.util.entity.dao.EntityDaoBase;
+import org.killbill.billing.util.entity.dao.EntitySqlDao;
import org.killbill.billing.util.entity.dao.EntitySqlDaoTransactionWrapper;
import org.killbill.billing.util.entity.dao.EntitySqlDaoTransactionalJdbiWrapper;
import org.killbill.billing.util.entity.dao.EntitySqlDaoWrapperFactory;
@@ -339,12 +342,6 @@ public class DefaultSubscriptionDao extends EntityDaoBase<SubscriptionBundleMode
for (final UUID bundleId : subscriptionsFromAccountId.keySet()) {
final List<SubscriptionBase> subscriptionsForBundle = subscriptionsFromAccountId.get(bundleId);
- final Collection<UUID> subscriptionIdsForBundle = Collections2.transform(subscriptionsForBundle, new Function<SubscriptionBase, UUID>() {
- @Override
- public UUID apply(final SubscriptionBase input) {
- return input.getId();
- }
- });
final Multimap<UUID, SubscriptionBaseEvent> eventsForSubscriptions = ArrayListMultimap.create();
for (final SubscriptionBase cur : subscriptionsForBundle) {
@@ -434,7 +431,7 @@ public class DefaultSubscriptionDao extends EntityDaoBase<SubscriptionBundleMode
return transactionalSqlDao.execute(new EntitySqlDaoTransactionWrapper<SubscriptionBaseEvent>() {
@Override
public SubscriptionBaseEvent inTransaction(final EntitySqlDaoWrapperFactory entitySqlDaoWrapperFactory) throws Exception {
- SubscriptionEventModelDao model = entitySqlDaoWrapperFactory.become(SubscriptionEventSqlDao.class).getById(eventId.toString(), context);
+ final SubscriptionEventModelDao model = entitySqlDaoWrapperFactory.become(SubscriptionEventSqlDao.class).getById(eventId.toString(), context);
return SubscriptionEventModelDao.toSubscriptionEvent(model);
}
});
@@ -477,13 +474,12 @@ public class DefaultSubscriptionDao extends EntityDaoBase<SubscriptionBundleMode
@Override
public List<SubscriptionBaseEvent> inTransaction(final EntitySqlDaoWrapperFactory entitySqlDaoWrapperFactory) throws Exception {
final List<SubscriptionEventModelDao> eventModels = entitySqlDaoWrapperFactory.become(SubscriptionEventSqlDao.class).getFutureActiveEventForSubscription(subscriptionId.toString(), now, context);
- final List<SubscriptionBaseEvent> events = new ArrayList<SubscriptionBaseEvent>(Collections2.transform(eventModels, new Function<SubscriptionEventModelDao, SubscriptionBaseEvent>() {
+ return new ArrayList<SubscriptionBaseEvent>(Collections2.transform(eventModels, new Function<SubscriptionEventModelDao, SubscriptionBaseEvent>() {
@Override
public SubscriptionBaseEvent apply(@Nullable final SubscriptionEventModelDao input) {
return SubscriptionEventModelDao.toSubscriptionEvent(input);
}
}));
- return events;
}
});
}
@@ -505,7 +501,7 @@ public class DefaultSubscriptionDao extends EntityDaoBase<SubscriptionBundleMode
}
// Notify the Bus of the latest requested change, if needed
- if (initialEvents.size() > 0) {
+ if (!initialEvents.isEmpty()) {
notifyBusOfRequestedChange(entitySqlDaoWrapperFactory, subscription, initialEvents.get(initialEvents.size() - 1), SubscriptionBaseTransitionType.CREATE, context);
}
return null;
@@ -514,33 +510,31 @@ public class DefaultSubscriptionDao extends EntityDaoBase<SubscriptionBundleMode
}
@Override
- public void createSubscriptionsWithAddOns(final List<DefaultSubscriptionBaseWithAddOns> subscriptions, final Map<UUID, List<SubscriptionBaseEvent>> initialEventsMap, final InternalCallContext context) {
+ public void createSubscriptionsWithAddOns(final List<SubscriptionBaseWithAddOns> subscriptions, final Map<UUID, List<SubscriptionBaseEvent>> initialEventsMap, final InternalCallContext context) {
transactionalSqlDao.execute(new EntitySqlDaoTransactionWrapper<Void>() {
@Override
public Void inTransaction(final EntitySqlDaoWrapperFactory entitySqlDaoWrapperFactory) throws Exception {
final SubscriptionSqlDao transactional = entitySqlDaoWrapperFactory.become(SubscriptionSqlDao.class);
final SubscriptionEventSqlDao eventsDaoFromSameTransaction = entitySqlDaoWrapperFactory.become(SubscriptionEventSqlDao.class);
- for (DefaultSubscriptionBaseWithAddOns subscription : subscriptions) {
- List<DefaultSubscriptionBase> currentSubscriptionBaseList = ImmutableList.copyOf(Iterables.transform(subscription.getSubscriptionBaseList(), new Function<SubscriptionBase, DefaultSubscriptionBase>() {
- @Override
- public DefaultSubscriptionBase apply(final SubscriptionBase input) {
- return (DefaultSubscriptionBase) input;
- }
- }));
- for (DefaultSubscriptionBase subscriptionBase : currentSubscriptionBaseList) {
- transactional.create(new SubscriptionModelDao(subscriptionBase), context);
- final List<SubscriptionBaseEvent> initialEvents = initialEventsMap.get(subscriptionBase.getId());
+ for (final SubscriptionBaseWithAddOns subscription : subscriptions) {
+ for (final SubscriptionBase subscriptionBase : subscription.getSubscriptionBaseList()) {
+ // Safe cast
+ final DefaultSubscriptionBase defaultSubscriptionBase = (DefaultSubscriptionBase) subscriptionBase;
+
+ transactional.create(new SubscriptionModelDao(defaultSubscriptionBase), context);
+
+ final List<SubscriptionBaseEvent> initialEvents = initialEventsMap.get(defaultSubscriptionBase.getId());
for (final SubscriptionBaseEvent cur : initialEvents) {
eventsDaoFromSameTransaction.create(new SubscriptionEventModelDao(cur), context);
final boolean isBusEvent = cur.getEffectiveDate().compareTo(clock.getUTCNow()) <= 0 && (cur.getType() == EventType.API_USER);
- recordBusOrFutureNotificationFromTransaction(subscriptionBase, cur, entitySqlDaoWrapperFactory, isBusEvent, 0, context);
-
+ recordBusOrFutureNotificationFromTransaction(defaultSubscriptionBase, cur, entitySqlDaoWrapperFactory, isBusEvent, 0, context);
}
+
// Notify the Bus of the latest requested change, if needed
- if (initialEvents.size() > 0) {
- notifyBusOfRequestedChange(entitySqlDaoWrapperFactory, subscriptionBase, initialEvents.get(initialEvents.size() - 1), SubscriptionBaseTransitionType.CREATE, context);
+ if (!initialEvents.isEmpty()) {
+ notifyBusOfRequestedChange(entitySqlDaoWrapperFactory, defaultSubscriptionBase, initialEvents.get(initialEvents.size() - 1), SubscriptionBaseTransitionType.CREATE, context);
}
}
}
@@ -653,7 +647,7 @@ public class DefaultSubscriptionDao extends EntityDaoBase<SubscriptionBundleMode
});
}
- private List<SubscriptionBaseEvent> filterSubscriptionBaseEvents(final List<SubscriptionEventModelDao> models) {
+ private List<SubscriptionBaseEvent> filterSubscriptionBaseEvents(final Collection<SubscriptionEventModelDao> models) {
final Collection<SubscriptionEventModelDao> filteredModels = Collections2.filter(models, new Predicate<SubscriptionEventModelDao>() {
@Override
public boolean apply(@Nullable final SubscriptionEventModelDao input) {
@@ -738,7 +732,7 @@ public class DefaultSubscriptionDao extends EntityDaoBase<SubscriptionBundleMode
return futureEvent;
}
- private void unactivateEventFromTransaction(final SubscriptionEventModelDao event, final EntitySqlDaoWrapperFactory dao, final InternalCallContext context) {
+ private void unactivateEventFromTransaction(final Entity event, final EntitySqlDaoWrapperFactory dao, final InternalCallContext context) {
if (event != null) {
final String eventId = event.getId().toString();
dao.become(SubscriptionEventSqlDao.class).unactiveEvent(eventId, context);
@@ -774,15 +768,15 @@ public class DefaultSubscriptionDao extends EntityDaoBase<SubscriptionBundleMode
}
private List<SubscriptionBase> buildBundleSubscriptions(final List<SubscriptionBase> input, @Nullable final Multimap<UUID, SubscriptionBaseEvent> eventsForSubscription,
- @Nullable List<SubscriptionBaseEvent> dryRunEvents, final InternalTenantContext context) throws CatalogApiException {
- if (input == null || input.size() == 0) {
+ @Nullable final Collection<SubscriptionBaseEvent> dryRunEvents, final InternalTenantContext context) throws CatalogApiException {
+ if (input == null || input.isEmpty()) {
return Collections.emptyList();
}
// Make sure BasePlan -- if exists-- is first
Collections.sort(input, DefaultSubscriptionInternalApi.SUBSCRIPTIONS_COMPARATOR);
- final List<ApiEventChange> baseChangeEvents = new LinkedList<ApiEventChange>();
+ final Collection<ApiEventChange> baseChangeEvents = new LinkedList<ApiEventChange>();
ApiEventCancel baseCancellationEvent = null;
final List<SubscriptionBase> result = new ArrayList<SubscriptionBase>(input.size());
for (final SubscriptionBase cur : input) {
@@ -856,11 +850,11 @@ public class DefaultSubscriptionDao extends EntityDaoBase<SubscriptionBundleMode
return result;
}
- private void mergeDryRunEvents(final UUID subscriptionId, final List<SubscriptionBaseEvent> events, @Nullable List<SubscriptionBaseEvent> dryRunEvents) {
+ private void mergeDryRunEvents(final UUID subscriptionId, final List<SubscriptionBaseEvent> events, @Nullable final Collection<SubscriptionBaseEvent> dryRunEvents) {
if (dryRunEvents == null || dryRunEvents.isEmpty()) {
return;
}
- for (SubscriptionBaseEvent curDryRun : dryRunEvents) {
+ for (final SubscriptionBaseEvent curDryRun : dryRunEvents) {
if (curDryRun.getSubscriptionId() != null && curDryRun.getSubscriptionId().equals(subscriptionId)) {
//boolean inserted = false;
@@ -951,9 +945,9 @@ public class DefaultSubscriptionDao extends EntityDaoBase<SubscriptionBundleMode
}
- private DefaultSubscriptionBase createSubscriptionForInternalUse(final SubscriptionBase shellSubscription, final List<SubscriptionBaseEvent> events, final InternalTenantContext context) throws CatalogApiException {
+ private SubscriptionBase createSubscriptionForInternalUse(final SubscriptionBase shellSubscription, final List<SubscriptionBaseEvent> events, final InternalTenantContext context) throws CatalogApiException {
final DefaultSubscriptionBase result = new DefaultSubscriptionBase(new SubscriptionBuilder(((DefaultSubscriptionBase) shellSubscription)), null, clock);
- if (events.size() > 0) {
+ if (!events.isEmpty()) {
final Catalog fullCatalog = catalogService.getFullCatalog(true, true, context);
result.rebuildTransitions(events, fullCatalog);
}
@@ -1029,14 +1023,14 @@ public class DefaultSubscriptionDao extends EntityDaoBase<SubscriptionBundleMode
final NotificationQueue subscriptionEventQueue = notificationQueueService.getNotificationQueue(DefaultSubscriptionBaseService.SUBSCRIPTION_SERVICE_NAME,
DefaultSubscriptionBaseService.NOTIFICATION_QUEUE_NAME);
subscriptionEventQueue.recordFutureNotificationFromTransaction(entitySqlDaoWrapperFactory.getHandle().getConnection(), effectiveDate, notificationKey, context.getUserToken(), context.getAccountRecordId(), context.getTenantRecordId());
- } catch (NoSuchNotificationQueue e) {
+ } catch (final NoSuchNotificationQueue e) {
throw new RuntimeException(e);
- } catch (IOException e) {
+ } catch (final IOException e) {
throw new RuntimeException(e);
}
}
- private void transferBundleDataFromTransaction(final BundleTransferData bundleTransferData, final SubscriptionEventSqlDao transactional,
+ private void transferBundleDataFromTransaction(final BundleTransferData bundleTransferData, final EntitySqlDao transactional,
final EntitySqlDaoWrapperFactory entitySqlDaoWrapperFactory, final InternalCallContext context) throws EntityPersistenceException {
final SubscriptionSqlDao transSubDao = entitySqlDaoWrapperFactory.become(SubscriptionSqlDao.class);
@@ -1045,7 +1039,7 @@ public class DefaultSubscriptionDao extends EntityDaoBase<SubscriptionBundleMode
final DefaultSubscriptionBaseBundle bundleData = bundleTransferData.getData();
final List<SubscriptionBundleModelDao> existingBundleModels = transBundleDao.getBundlesFromAccountAndKey(bundleData.getAccountId().toString(), bundleData.getExternalKey(), context);
- if (existingBundleModels.size() != 0) {
+ if (!existingBundleModels.isEmpty()) {
log.warn("Bundle already exists for accountId='{}', bundleExternalKey='{}'", bundleData.getAccountId(), bundleData.getExternalKey());
return;
}
@@ -1072,7 +1066,7 @@ public class DefaultSubscriptionDao extends EntityDaoBase<SubscriptionBundleMode
//
// Creates a copy of the existing subscriptions whose 'transitions' will reflect the new event
//
- private DefaultSubscriptionBase createSubscriptionWithNewEvent(final DefaultSubscriptionBase subscription, SubscriptionBaseEvent newEvent, final InternalTenantContext context) throws CatalogApiException {
+ private DefaultSubscriptionBase createSubscriptionWithNewEvent(final DefaultSubscriptionBase subscription, final SubscriptionBaseEvent newEvent, final InternalTenantContext context) throws CatalogApiException {
final DefaultSubscriptionBase subscriptionWithNewEvent = new DefaultSubscriptionBase(subscription, null, clock);
final List<SubscriptionBaseEvent> allEvents = new LinkedList<SubscriptionBaseEvent>();
diff --git a/subscription/src/main/java/org/killbill/billing/subscription/engine/dao/SubscriptionDao.java b/subscription/src/main/java/org/killbill/billing/subscription/engine/dao/SubscriptionDao.java
index 7c5743d..3430d2e 100644
--- a/subscription/src/main/java/org/killbill/billing/subscription/engine/dao/SubscriptionDao.java
+++ b/subscription/src/main/java/org/killbill/billing/subscription/engine/dao/SubscriptionDao.java
@@ -25,6 +25,7 @@ import org.killbill.billing.callcontext.InternalTenantContext;
import org.killbill.billing.catalog.api.CatalogApiException;
import org.killbill.billing.entitlement.api.SubscriptionApiException;
import org.killbill.billing.subscription.api.SubscriptionBase;
+import org.killbill.billing.subscription.api.SubscriptionBaseWithAddOns;
import org.killbill.billing.subscription.api.transfer.BundleTransferData;
import org.killbill.billing.subscription.api.transfer.TransferCancelData;
import org.killbill.billing.subscription.api.user.DefaultSubscriptionBase;
@@ -82,7 +83,7 @@ public interface SubscriptionDao extends EntityDao<SubscriptionBundleModelDao, S
// SubscriptionBase creation, cancellation, changePlanWithRequestedDate apis
public void createSubscription(DefaultSubscriptionBase subscription, List<SubscriptionBaseEvent> initialEvents, InternalCallContext context);
- public void createSubscriptionsWithAddOns(List<DefaultSubscriptionBaseWithAddOns> subscriptions, Map<UUID, List<SubscriptionBaseEvent>> initialEventsMap, InternalCallContext context);
+ public void createSubscriptionsWithAddOns(List<SubscriptionBaseWithAddOns> subscriptions, Map<UUID, List<SubscriptionBaseEvent>> initialEventsMap, InternalCallContext context);
public void cancelSubscriptionsOnBasePlanEvent(DefaultSubscriptionBase subscription, SubscriptionBaseEvent event, List<DefaultSubscriptionBase> subscriptions, List<SubscriptionBaseEvent> cancelEvents, InternalCallContext context);
diff --git a/subscription/src/main/resources/org/killbill/billing/subscription/ddl.sql b/subscription/src/main/resources/org/killbill/billing/subscription/ddl.sql
index 80abc65..968b006 100644
--- a/subscription/src/main/resources/org/killbill/billing/subscription/ddl.sql
+++ b/subscription/src/main/resources/org/killbill/billing/subscription/ddl.sql
@@ -1,4 +1,4 @@
-/*! SET storage_engine=INNODB */;
+/*! SET default_storage_engine=INNODB */;
DROP TABLE IF EXISTS subscription_events;
CREATE TABLE subscription_events (
diff --git a/subscription/src/test/java/org/killbill/billing/subscription/engine/dao/MockSubscriptionDaoMemory.java b/subscription/src/test/java/org/killbill/billing/subscription/engine/dao/MockSubscriptionDaoMemory.java
index d2306f1..8fc4b4b 100644
--- a/subscription/src/test/java/org/killbill/billing/subscription/engine/dao/MockSubscriptionDaoMemory.java
+++ b/subscription/src/test/java/org/killbill/billing/subscription/engine/dao/MockSubscriptionDaoMemory.java
@@ -38,6 +38,7 @@ import org.killbill.billing.catalog.api.TimeUnit;
import org.killbill.billing.dao.MockNonEntityDao;
import org.killbill.billing.entitlement.api.SubscriptionApiException;
import org.killbill.billing.subscription.api.SubscriptionBase;
+import org.killbill.billing.subscription.api.SubscriptionBaseWithAddOns;
import org.killbill.billing.subscription.api.transfer.BundleTransferData;
import org.killbill.billing.subscription.api.transfer.TransferCancelData;
import org.killbill.billing.subscription.api.user.DefaultEffectiveSubscriptionEvent;
@@ -224,24 +225,19 @@ public class MockSubscriptionDaoMemory extends MockEntityDaoBase<SubscriptionBun
mockNonEntityDao.addTenantRecordIdMapping(updatedSubscription.getId(), context);
}
- public void createSubscriptionsWithAddOns(final List<DefaultSubscriptionBaseWithAddOns> subscriptions,
+ @Override
+ public void createSubscriptionsWithAddOns(final List<SubscriptionBaseWithAddOns> subscriptions,
final Map<UUID, List<SubscriptionBaseEvent>> initialEventsMap,
final InternalCallContext context) {
synchronized (events) {
- for (DefaultSubscriptionBaseWithAddOns subscription : subscriptions) {
- List<DefaultSubscriptionBase> currentSubscriptionBaseList = ImmutableList.copyOf(Iterables.transform(subscription.getSubscriptionBaseList(), new Function<SubscriptionBase, DefaultSubscriptionBase>() {
- @Override
- public DefaultSubscriptionBase apply(final SubscriptionBase input) {
- return (DefaultSubscriptionBase) input;
- }
- }));
- for (DefaultSubscriptionBase subscriptionBase : currentSubscriptionBaseList) {
+ for (final SubscriptionBaseWithAddOns subscription : subscriptions) {
+ for (final SubscriptionBase subscriptionBase : subscription.getSubscriptionBaseList()) {
final List<SubscriptionBaseEvent> initialEvents = initialEventsMap.get(subscriptionBase.getId());
events.addAll(initialEvents);
for (final SubscriptionBaseEvent cur : initialEvents) {
recordFutureNotificationFromTransaction(null, cur.getEffectiveDate(), new SubscriptionNotificationKey(cur.getId()), context);
}
- final SubscriptionBase updatedSubscription = buildSubscription(subscriptionBase, context);
+ final SubscriptionBase updatedSubscription = buildSubscription((DefaultSubscriptionBase) subscriptionBase, context);
this.subscriptions.add(updatedSubscription);
mockNonEntityDao.addTenantRecordIdMapping(updatedSubscription.getId(), context);
}
diff --git a/tenant/src/main/resources/org/killbill/billing/tenant/ddl.sql b/tenant/src/main/resources/org/killbill/billing/tenant/ddl.sql
index 988714f..152521c 100644
--- a/tenant/src/main/resources/org/killbill/billing/tenant/ddl.sql
+++ b/tenant/src/main/resources/org/killbill/billing/tenant/ddl.sql
@@ -1,4 +1,4 @@
-/*! SET storage_engine=INNODB */;
+/*! SET default_storage_engine=INNODB */;
DROP TABLE IF EXISTS tenants;
CREATE TABLE tenants (
diff --git a/usage/src/main/resources/org/killbill/billing/usage/ddl.sql b/usage/src/main/resources/org/killbill/billing/usage/ddl.sql
index 12940eb..fbb27b1 100644
--- a/usage/src/main/resources/org/killbill/billing/usage/ddl.sql
+++ b/usage/src/main/resources/org/killbill/billing/usage/ddl.sql
@@ -1,4 +1,4 @@
-/*! SET storage_engine=INNODB */;
+/*! SET default_storage_engine=INNODB */;
DROP TABLE IF EXISTS rolled_up_usage;
CREATE TABLE rolled_up_usage (
diff --git a/util/src/main/java/org/killbill/billing/util/security/shiro/dao/JDBCSessionDao.java b/util/src/main/java/org/killbill/billing/util/security/shiro/dao/JDBCSessionDao.java
index ac29706..41a05eb 100644
--- a/util/src/main/java/org/killbill/billing/util/security/shiro/dao/JDBCSessionDao.java
+++ b/util/src/main/java/org/killbill/billing/util/security/shiro/dao/JDBCSessionDao.java
@@ -20,14 +20,14 @@ package org.killbill.billing.util.security.shiro.dao;
import java.io.IOException;
import java.io.Serializable;
+import java.util.UUID;
import javax.inject.Inject;
import org.apache.shiro.session.Session;
import org.apache.shiro.session.mgt.eis.CachingSessionDAO;
+import org.killbill.billing.util.UUIDs;
import org.skife.jdbi.v2.IDBI;
-import org.skife.jdbi.v2.Transaction;
-import org.skife.jdbi.v2.TransactionStatus;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -54,15 +54,10 @@ public class JDBCSessionDao extends CachingSessionDAO {
@Override
protected Serializable doCreate(final Session session) {
- final Serializable sessionId = jdbcSessionSqlDao.inTransaction(new Transaction<Long, JDBCSessionSqlDao>() {
- @Override
- public Long inTransaction(final JDBCSessionSqlDao transactional, final TransactionStatus status) throws Exception {
- transactional.create(new SessionModelDao(session));
- return transactional.getLastInsertId();
- }
- });
+ final UUID sessionId = UUIDs.randomUUID();
// See SessionModelDao#toSimpleSession for why we use toString()
assignSessionId(session, sessionId.toString());
+ jdbcSessionSqlDao.create(new SessionModelDao(session));
return sessionId;
}
@@ -73,15 +68,9 @@ public class JDBCSessionDao extends CachingSessionDAO {
return null;
}
- // Ignore unsupported JSESSIONID cookies
- final Long recordId;
- try {
- recordId = Long.parseLong(sessionId.toString().trim());
- } catch (final NumberFormatException e) {
- return null;
- }
+ final String sessionIdString = sessionId.toString();
+ final SessionModelDao sessionModelDao = jdbcSessionSqlDao.read(sessionIdString);
- final SessionModelDao sessionModelDao = jdbcSessionSqlDao.read(recordId);
if (sessionModelDao == null) {
return null;
}
diff --git a/util/src/main/java/org/killbill/billing/util/security/shiro/dao/JDBCSessionSqlDao.java b/util/src/main/java/org/killbill/billing/util/security/shiro/dao/JDBCSessionSqlDao.java
index f8d9322..f277430 100644
--- a/util/src/main/java/org/killbill/billing/util/security/shiro/dao/JDBCSessionSqlDao.java
+++ b/util/src/main/java/org/killbill/billing/util/security/shiro/dao/JDBCSessionSqlDao.java
@@ -29,7 +29,7 @@ import org.skife.jdbi.v2.sqlobject.mixins.Transactional;
public interface JDBCSessionSqlDao extends Transactional<JDBCSessionSqlDao> {
@SqlQuery
- public SessionModelDao read(@Bind("recordId") final Long sessionId);
+ public SessionModelDao read(@Bind("id") final String sessionId);
@SqlUpdate
public void create(@SmartBindBean final SessionModelDao sessionModelDao);
@@ -40,6 +40,4 @@ public interface JDBCSessionSqlDao extends Transactional<JDBCSessionSqlDao> {
@SqlUpdate
public void delete(@SmartBindBean final SessionModelDao sessionModelDao);
- @SqlQuery
- public Long getLastInsertId();
}
diff --git a/util/src/main/java/org/killbill/billing/util/security/shiro/dao/SessionModelDao.java b/util/src/main/java/org/killbill/billing/util/security/shiro/dao/SessionModelDao.java
index acfd28a..46341cb 100644
--- a/util/src/main/java/org/killbill/billing/util/security/shiro/dao/SessionModelDao.java
+++ b/util/src/main/java/org/killbill/billing/util/security/shiro/dao/SessionModelDao.java
@@ -33,6 +33,7 @@ public class SessionModelDao {
private final Serializer<Map> serializer = new DefaultSerializer<Map>();
private Long recordId;
+ private String id;
private DateTime startTimestamp;
private DateTime lastAccessTime;
private long timeout;
@@ -42,7 +43,7 @@ public class SessionModelDao {
public SessionModelDao() { /* For the DAO mapper */ }
public SessionModelDao(final Session session) {
- this.recordId = session.getId() == null ? null : Long.valueOf(session.getId().toString());
+ this.id = session.getId() == null ? null : session.getId().toString();
this.startTimestamp = new DateTime(session.getStartTimestamp(), DateTimeZone.UTC);
this.lastAccessTime = new DateTime(session.getLastAccessTime(), DateTimeZone.UTC);
this.timeout = session.getTimeout();
@@ -56,11 +57,11 @@ public class SessionModelDao {
public Session toSimpleSession() throws IOException {
final SimpleSession simpleSession = new SimpleSession();
- if (recordId != null) {
+ if (id != null) {
// Make sure to use a String here! It will be used as-is as the key in Ehcache.
- // When retrieving the session, the sessionId will be a String: if a Long is used,
- // the lookup will trigger a miss. See https://github.com/killbill/killbill/issues/299
- simpleSession.setId(recordId.toString());
+ // When retrieving the session, the sessionId will be a String
+ // See https://github.com/killbill/killbill/issues/299
+ simpleSession.setId(id);
}
simpleSession.setStartTimestamp(startTimestamp.toDate());
simpleSession.setLastAccessTime(lastAccessTime.toDate());
@@ -78,6 +79,10 @@ public class SessionModelDao {
return recordId;
}
+ public String getId() {
+ return id;
+ }
+
public DateTime getStartTimestamp() {
return startTimestamp;
}
@@ -102,6 +107,7 @@ public class SessionModelDao {
public String toString() {
final StringBuilder sb = new StringBuilder("SessionModelDao{");
sb.append("recordId=").append(recordId);
+ sb.append(", id='").append(id).append('\'');
sb.append(", startTimestamp=").append(startTimestamp);
sb.append(", lastAccessTime=").append(lastAccessTime);
sb.append(", timeout=").append(timeout);
@@ -125,33 +131,34 @@ public class SessionModelDao {
if (timeout != that.timeout) {
return false;
}
- if (host != null ? !host.equals(that.host) : that.host != null) {
+ if (recordId != null ? !recordId.equals(that.recordId) : that.recordId != null) {
return false;
}
- if (lastAccessTime != null ? !lastAccessTime.equals(that.lastAccessTime) : that.lastAccessTime != null) {
+ if (id != null ? !id.equals(that.id) : that.id != null) {
return false;
}
- if (recordId != null ? !recordId.equals(that.recordId) : that.recordId != null) {
+ if (startTimestamp != null ? !startTimestamp.equals(that.startTimestamp) : that.startTimestamp != null) {
return false;
}
- if (!Arrays.equals(sessionData, that.sessionData)) {
+ if (lastAccessTime != null ? !lastAccessTime.equals(that.lastAccessTime) : that.lastAccessTime != null) {
return false;
}
- if (startTimestamp != null ? !startTimestamp.equals(that.startTimestamp) : that.startTimestamp != null) {
+ if (host != null ? !host.equals(that.host) : that.host != null) {
return false;
}
+ return Arrays.equals(sessionData, that.sessionData);
- return true;
}
@Override
public int hashCode() {
int result = recordId != null ? recordId.hashCode() : 0;
+ result = 31 * result + (id != null ? id.hashCode() : 0);
result = 31 * result + (startTimestamp != null ? startTimestamp.hashCode() : 0);
result = 31 * result + (lastAccessTime != null ? lastAccessTime.hashCode() : 0);
result = 31 * result + (int) (timeout ^ (timeout >>> 32));
result = 31 * result + (host != null ? host.hashCode() : 0);
- result = 31 * result + (sessionData != null ? Arrays.hashCode(sessionData) : 0);
+ result = 31 * result + Arrays.hashCode(sessionData);
return result;
}
diff --git a/util/src/main/resources/org/killbill/billing/util/ddl.sql b/util/src/main/resources/org/killbill/billing/util/ddl.sql
index 7cd9a43..8e21ad6 100644
--- a/util/src/main/resources/org/killbill/billing/util/ddl.sql
+++ b/util/src/main/resources/org/killbill/billing/util/ddl.sql
@@ -1,4 +1,4 @@
-/*! SET storage_engine=INNODB */;
+/*! SET default_storage_engine=INNODB */;
DROP TABLE IF EXISTS custom_fields;
CREATE TABLE custom_fields (
@@ -235,6 +235,7 @@ CREATE TABLE bus_events_history (
drop table if exists sessions;
create table sessions (
record_id serial unique
+, id varchar(36) NOT NULL
, start_timestamp datetime not null
, last_access_time datetime default null
, timeout int
@@ -242,6 +243,7 @@ create table sessions (
, session_data mediumblob default null
, primary key(record_id)
) /*! CHARACTER SET utf8 COLLATE utf8_bin */;
+CREATE UNIQUE INDEX sessions_id ON sessions(id);
DROP TABLE IF EXISTS users;
diff --git a/util/src/main/resources/org/killbill/billing/util/migration/V20161105000000__session_id.sql b/util/src/main/resources/org/killbill/billing/util/migration/V20161105000000__session_id.sql
new file mode 100644
index 0000000..cce5c63
--- /dev/null
+++ b/util/src/main/resources/org/killbill/billing/util/migration/V20161105000000__session_id.sql
@@ -0,0 +1,3 @@
+alter table sessions add column id varchar(36) not null after record_id;
+update sessions set id = record_id;
+create unique index sessions_id on sessions(id);
\ No newline at end of file
diff --git a/util/src/main/resources/org/killbill/billing/util/security/shiro/dao/JDBCSessionSqlDao.sql.stg b/util/src/main/resources/org/killbill/billing/util/security/shiro/dao/JDBCSessionSqlDao.sql.stg
index fe228d2..b002312 100644
--- a/util/src/main/resources/org/killbill/billing/util/security/shiro/dao/JDBCSessionSqlDao.sql.stg
+++ b/util/src/main/resources/org/killbill/billing/util/security/shiro/dao/JDBCSessionSqlDao.sql.stg
@@ -3,25 +3,28 @@ group JDBCSessionSqlDao;
read() ::= <<
select
record_id
+, id
, start_timestamp
, last_access_time
, timeout
, host
, session_data
from sessions
-where record_id = :recordId
+where id = :id
;
>>
create() ::= <<
insert into sessions (
- start_timestamp
+ id
+, start_timestamp
, last_access_time
, timeout
, host
, session_data
) values (
- :startTimestamp
+ :id
+, :startTimestamp
, :lastAccessTime
, :timeout
, :host
@@ -36,16 +39,12 @@ update sessions set
, timeout = :timeout
, host = :host
, session_data = :sessionData
-where record_id = :recordId
+where id = :id
;
>>
delete() ::= <<
delete from sessions
-where record_id = :recordId
+where id = :id
;
->>
-
-getLastInsertId() ::= <<
-select LAST_INSERT_ID();
->>
+>>
\ No newline at end of file
diff --git a/util/src/test/resources/org/killbill/billing/util/ddl_test.sql b/util/src/test/resources/org/killbill/billing/util/ddl_test.sql
index 6269d08..39e4b29 100644
--- a/util/src/test/resources/org/killbill/billing/util/ddl_test.sql
+++ b/util/src/test/resources/org/killbill/billing/util/ddl_test.sql
@@ -1,4 +1,4 @@
-/*! SET storage_engine=INNODB */;
+/*! SET default_storage_engine=INNODB */;
DROP TABLE IF EXISTS dummy;
CREATE TABLE dummy (